lserman / capistrano-elbas Goto Github PK
View Code? Open in Web Editor NEWDeploy Rails apps to AWS AutoScale groups
License: MIT License
Deploy Rails apps to AWS AutoScale groups
License: MIT License
This was done in #24 but I won't be merging that as it is for an unsupported version of this gem.
I am about to start using elbas as it looks like a great way to automate our autoscaling deployments.
However, I notice that you recommend this setting:
set :aws_no_reboot_on_create_ami, true
Creating an AMI without reboot does not guarantee that the AMI will be in a consistent state. There are warnings about this throughout the AWS docs.
I would think that since this is an autoscaling group, it's really not a big deal for a single instance to go down while creating the AMI since the ELB will route traffic to the other instances in the meantime.
Any particular reason for not rebooting the instance to create the AMI with elbas?
How could I achieve this?
I'm left with many volumes that I'd like deleted after the instances are terminated.
Thank you
I have an autoscale group for my workers and one for my application servers:
autoscale 'application-box', user: 'deploy', roles: [:app]
autoscale 'worker-box', user: 'deploy', roles: [:worker]
However, when I finish my deployment, it only updates the Launch Configuration for one of the Auto Scale groups
Sometimes you need to run rails c
on your servers or something and it's a pain with an ELB. You don't know the server IPs of your instances without checking the AWS console so you cannot SSH into one of them to run whatever you need to run.
Since elbas has knowledge of your load balancer, environment, and AWS credentials, it would be great if you could run something like bin/cap production elbas:server_ips
or something to see a list of public IPs (if available) on that environment's ELB.
This is a unique variable:
I have to have two different staging/deployment scripts as a work around at the moment.
In our setup developer are authenticated through our company but use a role on client company to deploy on their behalf and on their account.
Therefore we ask our client to create a role for us which we can assume for the intervention we do on their account.
I've added this patch which check for a aws_assumed_role_arn
key in capistrano config and if present start a special session.
I do not know how frequent our setup is but I'm sharing the code back with you since your gem basically saved me days of work :)
require 'aws/sts'
require 'elbas/aws/credentials'
Elbas::AWS::Credentials.module_eval do
def overidden_credentials
@_credentials ||= begin
_credentials = {
access_key_id: fetch(:aws_access_key_id, ENV['AWS_ACCESS_KEY_ID']),
secret_access_key: fetch(:aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY'])
}
_credentials.merge! region: fetch(:aws_region) if fetch(:aws_region)
_credentials
end
end
def credentials
return @patched_credentials if defined?(@patched_credentials)
credential_hash = overidden_credentials
assumed_role_arn = fetch(:aws_assumed_role_arn)
if assumed_role_arn
sts = ::AWS::STS.new(credential_hash)
role_credentials = sts.assume_role(
role_arn: assumed_role_arn,
role_session_name: "capistrano-session",
)
@patched_credentials = role_credentials[:credentials].merge(region: credential_hash[:region])
else
@patched_credentials = credential_hash
end
@patched_credentials
end
end
** Invoke production (first_time)
** Execute production
** Invoke load:defaults (first_time)
** Execute load:defaults
cap aborted!
NameError: uninitialized constant AWS
Did you mean? Aws
/Users/me/.rvm/gems/ruby-2.3.4/gems/elbas-0.0.4/lib/elbas/capistrano.rb:24:in `autoscaling'
/Users/me/.rvm/gems/ruby-2.3.4/gems/elbas-0.0.4/lib/elbas/capistrano.rb:9:in `autoscale'
config/deploy/production.rb:4:in `<top (required)>'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/lib/capistrano/setup.rb:28:in `load'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/lib/capistrano/setup.rb:28:in `block (3 levels) in <top (required)>'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/lib/capistrano/configuration/variables.rb:32:in `untrusted!'
/Users/me/.rvm/rubies/ruby-2.3.4/lib/ruby/2.3.0/delegate.rb:83:in `method_missing'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/lib/capistrano/setup.rb:26:in `block (2 levels) in <top (required)>'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:251:in `block in execute'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:251:in `each'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:251:in `execute'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:195:in `block in invoke_with_call_chain'
/Users/me/.rvm/rubies/ruby-2.3.4/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:188:in `invoke_with_call_chain'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/task.rb:181:in `invoke'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:160:in `invoke_task'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:116:in `each'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:116:in `block in top_level'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:125:in `run_with_threads'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:110:in `top_level'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:83:in `block in run'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:186:in `standard_exception_handling'
/Users/me/.rvm/gems/ruby-2.3.4/gems/rake-12.3.0/lib/rake/application.rb:80:in `run'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/lib/capistrano/application.rb:14:in `run'
/Users/me/.rvm/gems/ruby-2.3.4/gems/capistrano-3.7.2/bin/cap:3:in `<top (required)>'
/Users/me/.rvm/gems/ruby-2.3.4/bin/cap:23:in `load'
/Users/me/.rvm/gems/ruby-2.3.4/bin/cap:23:in `<main>'
/Users/me/.rvm/gems/ruby-2.3.4/bin/ruby_executable_hooks:15:in `eval'
/Users/me/.rvm/gems/ruby-2.3.4/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => production
I'm experiencing an issue where Capistrano only deploys to a single server, despite having multiple running servers in my AutoScalingGroup.
My setup on AWS:
A launch template (id: lt-xxx, name: preprod)
An autoscaling group (name: preprod)
2 running instances launched by the ASG (Ids: i-x1 and i-x2)
Below is the output of instantiating an Elbas::AWS::AutoscaleGroup, calling instances.running, and creating a new Elbas::AWS::InstanceCollection with the IDs I can see in the ASG:
asg = Elbas::AWS::AutoscaleGroup.new preprod
=> #<Elbas::AWS::AutoscaleGroup:0x000000000351efc0
@aws_client=#<Aws::AutoScaling::Client>,
@aws_counterpart=
#<struct Aws::AutoScaling::Types::AutoScalingGroup
auto_scaling_group_name="preprod",
auto_scaling_group_arn="arn:xxx",
launch_configuration_name=nil,
launch_template=#<struct Aws::AutoScaling::Types::LaunchTemplateSpecification launch_template_id="lt-xxx", launch_template_name="preprod", version="$Latest">,
mixed_instances_policy=nil,
min_size=0,
max_size=2,
desired_capacity=2,
default_cooldown=300,
availability_zones=["eu-west-1b", "eu-west-1a"],
load_balancer_names=[],
target_group_arns=["arn:xxx"],
health_check_type="EC2",
health_check_grace_period=300,
instances=
[#<struct Aws::AutoScaling::Types::Instance
instance_id="i-x1",
availability_zone="eu-west-1b",
lifecycle_state="InService",
health_status="Healthy",
launch_configuration_name=nil,
launch_template=#<struct Aws::AutoScaling::Types::LaunchTemplateSpecification launch_template_id="lt-xxx", launch_template_name="preprod", version="3">,
protected_from_scale_in=false>,
#<struct Aws::AutoScaling::Types::Instance
instance_id="i-x2",
availability_zone="eu-west-1a",
lifecycle_state="InService",
health_status="Healthy",
launch_configuration_name=nil,
launch_template=#<struct Aws::AutoScaling::Types::LaunchTemplateSpecification launch_template_id="lt-xxx", launch_template_name="preprod", version="3">,
protected_from_scale_in=false>],
created_time=2019-02-25 14:44:39 UTC,
suspended_processes=[],
placement_group=nil,
vpc_zone_identifier="subnet-xxx,subnet-xxx",
enabled_metrics=[],
status=nil,
tags=[],
termination_policies=["Default"],
new_instances_protected_from_scale_in=false,
service_linked_role_arn="arn:aws:iam::xxx:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling">,
@name="preprod">
asg.instances.running
=> [#<Elbas::AWS::Instance:0x00000000094de348
@aws_client=#<Aws::EC2::Client>,
@aws_counterpart=#<Aws::EC2::Instance:0x00000000094a4530 @client=#<Aws::EC2::Client>, @data=nil, @id="i-x1">,
@id="i-x1",
@public_dns="xxx.eu-west-1.compute.amazonaws.com",
@state=16>]
collection = Elbas::AWS::InstanceCollection.new ["i-x1", "i-x2"]
=> #<Elbas::AWS::InstanceCollection:0x0000000008976be0
@aws_client=#<Aws::EC2::Client>,
@ids=["i-x1", "i-x2"],
@instances=
[#<Elbas::AWS::Instance:0x000000000885dad8
@aws_client=#<Aws::EC2::Client>,
@aws_counterpart=#<Aws::EC2::Instance:0x00000000087f9e70 @client=#<Aws::EC2::Client>, @data=nil, @id="i-x1">,
@id="i-x1",
@public_dns="xxx.eu-west-1.compute.amazonaws.com",
@state=16>]>
As you can see, when I instantiate the ASG, I can see 2 instances (i-x1 and i-x2), but calling
asg.instances.running
or
Elbas::AWS::InstanceCollection.new ["i-x1", "i-x2"]
I only get the first instance.
The issue seems to be in Elbas::AWS::InstanceCollection#query_instances_by_ids, which only looks at the first reservation in the response from describe_instances.
I'm submitting a PR, which changes the method to:
def query_instances_by_ids(ids)
aws_client
.describe_instances(instance_ids: @ids)
.reservations.map(&:instances).flatten
end
Please release the latest master onto rubygems.
I want to specify the role on the first instance in order to run scheduled works once.
The example is here:
https://github.com/mchicote/capistrano3-autoscaling-deploy#how-this-works
How do you think?
I wish you develop this function soon or I can help you to implement it.
In the capistrano.rb there exists an older style DSL for erroring in Capistrano:
error <<~MESSAGE
Could not create AMI because no running instances were found in the specified
AutoScale group. Ensure that the AutoScale group name is correct and that
there is at least one running instance attached to it.
MESSAGE
which is apparently not a method in capistrano dsl anymore. Just tracking the issue.
have a situation where we would prefer to run two different auto-scale groups (asg), one for web and one for workers, both based on the same ami, and only update the ami once.
Additionally, have a need to be able to create two different ami's, one for each asg
It appears that the task that updates the amis would only run once since capistrano only runs them once if we don't use invoke!
.
does elbas support multiple asgs where each has a separate launch template?
does elbas support multiple asg's where they all use the same launch template?
Does this gem suspend autoscaling during deployment? Because cant find in code
would be good for troubleshooting/rollback to have ability to spin up the previous ami. not currently possible since all old amis are deleted, even before the current ami snapshot is complete/available
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.