Reputation: 15022
I trying to run my production servers with AWS auto scaling framework.
I wonder how can I deploy the new published code into running production servers.
I don't care the down time
currently.
I run the web server with nginx
and puma
What's the common way to do this task ?
I think to login AWS console find all the servers IP and SSH into it. Update the codebase and restart the puma web server is not a good way to maintain quality product
Upvotes: 4
Views: 2784
Reputation: 14039
I have created a special Capistrano deploy environment. It won't be as powerful as other deployment services you would find out there, but it does the job.
The assumption is that you have a remote machine you can SSH into to launch the deployment command (I suppose your server don't have public IPs, but you still have one bastion host that you can SSH into and where you can run a capistrano task). The machine will get the dns of all other machines, and deploy to them using the Capistrano deployment pipeline (I have added the id_rsa of that deployment machine in the authorized_keys of the other guys).
I am using Amazon tags to filter the instances : make sure your instances of the autoscaling group can be selected easily using tags.
In the code below, I also produce a warning for machines that are not inside the autoscaling group, but still behind the same load-balancer (using tags again)
# config/deploy/remote_production.rb
# [ several lines of capistrano configuration : git repo, branch, etc.]
#
# Deploy to autoscaling machines :
#
# Determine list of instances with aws sdk
require 'aws-sdk'
# Get instances IDs using tags
ec2 = Aws::EC2::Client.new
instances_tagged = ec2.describe_instances(
dry_run: false,
filters: [
{
name: 'tag:environment',
values: ['production'],
},
{
name: 'tag:stack',
values: ['rails'],
}
],
)
dns_tagged = instances_tagged.reservations[0].instances.map(&:private_dns_name)
# Get auto scaling group instance IDs
as = Aws::AutoScaling::Client.new
instances_of_as = as.describe_auto_scaling_groups(
auto_scaling_group_names: ['myApp-autoScale-prod'],
max_records: 1,
).auto_scaling_groups[0].instances
if instances_of_as.empty?
autoscaling_dns = []
else
instances_ids = instances_of_as.map(&:instance_id)
autoscaling_dns = instance_ids.map do |instance_id|
ec2.instances[instance_id].private_dns_name
end
end
# Get private DNS names for each machine
dns = dns_tagged | autoscaling_dns
if (extra_instances = (dns - autoscaling_dns).size) != 0
puts "WARNING : there are #{extra_instances} more instances that just the ones of the autoscaling group !!"
end
# Set the Capistrano servers to deploy to
dns.each do |instance|
server instance,
roles: %w{web app db},
user: 'ubuntu',
port: 22,
ssh_options: {
keys: ['~/.ssh/id_rsa'],
forward_agent: true,
auth_methods: %w(publickey)
}
end
I just have to do
ssh ssh@bastion_host
cd deploy/myApp
cap remote_production deploy
Upvotes: 0
Reputation: 270224
There are many choices for ways to deploy code on an Amazon EC2 instance. In fact, it is mostly the same as how you would deploy code on any normal computer, but Amazon EC2 has a few techniques that could make this easier.
Option 1: Configure an AMI
When a new Amazon EC2 instance is launched, an Amazon Machine Image (AMI) must be selected. The AMI is a disk image that is copied to the boot disk of the new instance, and the instance then boots using that image.
So, one option for deploying new code is:
minimum
quantity of instances)minimum
and await automatic scale-down processes, or force the decrease by lowering the desired-capacity
. Older instances will automatically be removed first, based on the Auto Scaling Termination PolicyOption 2: User Data scripts
This is similar to Option 1, but instead of configuring a new AMI, have the instances self-configure via a startup script. A script can be passed via the User Data field and this script will execute when a new instance is launched.
The script can do whatever you wish, eg download and install software, deploy using Puppet/Chef/Ansible, and start/stop the web server.
The User Data script should be stored within the Auto Scaling Launch Configuration (similar to the AMI in Option 1). Then, simply launch new instances (similar to Option 1) and they will automatically configure themselves with the latest version of your software.
Option 3: Use a deployment service
AWS has several systems that can deploy code to Amazon EC2 instances, including:
The first three can deploy the infrastructure as well as the code.
While these systems are more complex than simply providing a script, they allow a more repeatable, resilient architecture (eg handling failures and roll-backs).
Upvotes: 6