Skip to content

Instantly share code, notes, and snippets.

@joker1007
Created May 11, 2016 10:54
Show Gist options
  • Save joker1007/7158adaf70c92e040741298251f9ec87 to your computer and use it in GitHub Desktop.
Save joker1007/7158adaf70c92e040741298251f9ec87 to your computer and use it in GitHub Desktop.
require 'pp'
require 'timeout'
require 'terminal-table'
require 'paint'
class EcsDeploy
WAIT_TIMEOUT = 300
CHECK_INTERVAL = 5
attr_reader \
:cluster, :service_name, :task_definition_name, :revision,
:elb_name, :elb_service_port, :elb_healthcheck_port, :elb_container_name,
:desired_count, :deployment_configuration,
:region,
:task_definition_options, :container_definitions,
:client
def initialize(
cluster:, service_name:, task_definition_name: nil, revision: nil,
elb_name: nil, elb_service_port: nil, elb_healthcheck_port: nil, elb_container_name: nil,
desired_count: 1, deployment_configuration: {maximum_percent: 200, minimum_healthy_percent: 100},
region: "ap-northeast-1",
task_definition_options: {}, container_definitions:
)
@cluster = cluster
@service_name = service_name
@task_definition_name = task_definition_name || service_name
@elb_name = elb_name
@elb_service_port = elb_service_port
@elb_healthcheck_port = elb_healthcheck_port
@elb_container_name = elb_container_name
@desired_count = desired_count
@deployment_configuration = deployment_configuration
@revision = revision
@region = region
@task_definition_options = task_definition_options
@container_definitions = container_definitions
@client = Aws::ECS::Client.new(region: region)
end
def get_latest_revision
begin
resp = client.describe_task_definition(task_definition: task_definition_name)
resp.task_definition.revision
rescue Aws::ECS::Errors::ClientException
nil
end
end
def create_or_update_service
if revision
client.describe_task_definition(task_definition: task_definition_name_with_revision(revision))
else
register_task_definition
end
res = client.describe_services(cluster: cluster, services: [service_name])
service_options = {
cluster: cluster,
task_definition: task_definition_name_with_revision(revision),
desired_count: desired_count,
deployment_configuration: deployment_configuration,
}
if res.services.empty?
puts "create service: #{service_name} [#{Paint['START', :green]}]"
service_options.merge!({service_name: service_name})
if elb_name
service_options.merge!({
role: "ecsServiceRole",
load_balancers: [
{
load_balancer_name: elb_name,
container_name: elb_container_name,
container_port: elb_service_port,
}
],
})
end
@response = client.create_service(service_options)
puts "create service: #{service_name} [#{Paint['DONE', :green]}]"
else
puts "update service: #{service_name} [#{Paint['START', :green]}]"
service_options.merge!({service: service_name})
@response = client.update_service(service_options)
puts "update service: #{service_name} [#{Paint['DONE', :green]}]"
end
end
def register_task_definition
puts "register task definition: #{task_definition_name} [#{Paint['START', :green]}]"
result = client.register_task_definition({
family: task_definition_name,
container_definitions: container_definitions,
}.merge(task_definition_options))
puts "register task definition: #{task_definition_name} [#{Paint['DONE', :green]}]"
pp result
end
def wait_service_is_running
return unless @response
service = @response.service
deployment = nil
# wait deployment start
Timeout.timeout(WAIT_TIMEOUT) do
begin
sleep CHECK_INTERVAL
service = client.describe_services(cluster: @cluster, services: [service.service_name]).services[0]
end until service.deployments.find { |d| service.task_definition == d.task_definition }
end
puts "ECS deployment: #{service.service_name} [#{Paint['START', :green]}]"
Timeout.timeout(WAIT_TIMEOUT) do
begin
sleep CHECK_INTERVAL
service = client.describe_services(cluster: @cluster, services: [service.service_name]).services[0]
deployment = service.deployments.find { |d| service.task_definition == d.task_definition }
rows = []
rows << [service.status, deployment.desired_count, deployment.pending_count, deployment.running_count]
table = Terminal::Table.new headings: ['Status', 'Desired Count', 'Pending Count', 'Running Count'], rows: rows
puts table
end until deployment.pending_count == 0 && deployment.desired_count == deployment.running_count
puts "ECS deployment: #{service.service_name} [#{Paint['DONE', :green]}]"
end
end
private
def task_definition_name_with_revision(revision)
suffix = revision ? ":#{revision}" : ""
"#{task_definition_name}#{suffix}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment