Class: EcsShip::Deploy

Inherits:
Object
  • Object
show all
Defined in:
lib/ecs_ship/deploy.rb

Instance Method Summary collapse

Constructor Details

#initialize(cluster_name, service_name, task_name, docker_image_name, docker_tag = 'latest') ⇒ Deploy

Returns a new instance of Deploy.



5
6
7
8
9
10
11
12
13
# File 'lib/ecs_ship/deploy.rb', line 5

def initialize(cluster_name, service_name, task_name, docker_image_name, docker_tag = 'latest')
  @cluster_name = cluster_name
  @docker_tag = docker_tag
  @service_name = service_name
  @task_name = task_name
  @docker_image_name = docker_image_name

  raise "Invalid cluster name, valid clusters are: #{cluster_names}" unless cluster_names.any?{|available_name| available_name == cluster_name}
end

Instance Method Details

#all_clustersObject



88
89
90
# File 'lib/ecs_ship/deploy.rb', line 88

def all_clusters
  @all_clusters ||= JSON.parse(`aws ecs describe-clusters --clusters #{cluster_arns.join(' ')}`)['clusters']
end

#cluster_arnsObject



92
93
94
# File 'lib/ecs_ship/deploy.rb', line 92

def cluster_arns
  JSON.parse(`aws ecs list-clusters`)['clusterArns']
end

#cluster_namesObject



96
97
98
# File 'lib/ecs_ship/deploy.rb', line 96

def cluster_names
  all_clusters.map{|c| c['clusterName']}
end

#deployObject



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/ecs_ship/deploy.rb', line 15

def deploy
  stop_existing_task
  rev_task_version
  start_updated_task

  puts "Shipped! #{@service_name} should now be running #{versioned_task_name}"

rescue StandardError => e
  syntax
  raise e
end

#rev_task_versionObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ecs_ship/deploy.rb', line 41

def rev_task_version
  begin
    puts 'Creating new task definition with updated version number'

    task_definition = JSON.parse(`aws ecs describe-task-definition --task-definition #{@task_name}`)['taskDefinition']

    @revision = task_definition['revision'] + 1

    registerable_params = [:family, :taskRoleArn, :networkMode, :containerDefinitions, :volumes, :placementConstraints]

    task_definition['containerDefinitions'].map! do |container_definition|
      if container_definition['image'].include?(@docker_image_name)
        container_definition['image'] = "#{@docker_image_name}:#{@docker_tag}"
      end
      container_definition
    end

    File.open(temp_definition_path, 'w') do |file|
      file.write(task_definition.select{|k, v| registerable_params.include?(k.to_sym)}.to_json)
    end

    success = system("aws ecs register-task-definition --family #{@task_name} --cli-input-json file://#{temp_definition_path}")
    unless success
      raise 'Failed to rev task version'
    end
  ensure
    File.delete(temp_definition_path)
  end
end

#start_updated_taskObject



75
76
77
78
79
80
81
82
# File 'lib/ecs_ship/deploy.rb', line 75

def start_updated_task
  puts 'Starting service back up with newly created task definition'

  success = system("aws ecs update-service --cluster #{@cluster_name} --service #{@service_name} --desired-count 1 --task-definition #{versioned_task_name}")
  unless success
    raise 'Failed to start back up the updated service'
  end
end

#stop_existing_taskObject



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ecs_ship/deploy.rb', line 27

def stop_existing_task
  puts 'Stopping existing task... yes this is a downtime deployment'

  running_task_arns = JSON.parse(`aws ecs list-tasks --cluster #{@cluster_name} --family #{@task_name} --desired-status RUNNING`)['taskArns']
  running_task_arns.each do |task_arn|
    system("aws ecs stop-task --cluster #{@cluster_name} --task #{task_arn}")
  end

  success = system("aws ecs update-service --cluster #{@cluster_name} --service #{@service_name} --desired-count 0")
  unless success
    raise 'Failed to stop existing task'
  end
end

#syntaxObject



100
101
102
103
104
# File 'lib/ecs_ship/deploy.rb', line 100

def syntax
  puts "Arguments: #{method(:initialize).parameters.map{|p| "#{p.last} (#{p.first})"}.join(' ')}"
  puts "\n"
  puts "Valid stacks: #{cluster_names}}"
end

#temp_definition_pathObject



71
72
73
# File 'lib/ecs_ship/deploy.rb', line 71

def temp_definition_path
  'temp_definition_delete_me.json'
end

#versioned_task_nameObject



84
85
86
# File 'lib/ecs_ship/deploy.rb', line 84

def versioned_task_name
  "#{@task_name}:#{@revision}"
end