Last time,
Next time, I'll try to create a database and insert the initial configuration as a last-minute task, rewrite the WordPress configuration file, and download the WordPress theme from GitHub.
However, due to my convenience, I used Capistrano3 to create an AWS EC2 instance, so I would like to leave the TIPS. In this article, we used the official AMI from the EC2 instances for deployment to set up EC2 instances in different areas with AvailabilityZones. As a pilot project, we will use Amazon Linux AMI 2014.03.2 (HVM), which supports the latest instance type "t2.micro", to simultaneously set up a total of 4 instances, 2 each in the AvailabilityZones of 1a and 1c in the Tokyo region.
- As a preliminary preparation, you need to set up the minimum necessary settings to create an EC2 instance such as a VPC or Subnet in the AWS account where the instance will be created. In particular, this time we will be setting up instances in different AvailabilityZones, so we need to set up Subnets in each zone.
Now, let's get to the deployment steps. To get started, edit 'config/deploy/test.rb' to configure the deployment environment (server). In this case, the dynamically created EC2 instance will be used as the deployment environment, so you cannot configure the server in advance. This is because new instances launched on AWS are not given an ElasticIP, so the PublicIP is different each time, and the endpoint URL changes dynamically. So, this time, after the instance is launched, we will set the target server in the Capistorano task. Since the initial server configuration is no longer necessary, I will comment out the description. In addition, only the SSH option will be used in common in the end, so I will leave it (although I will not use it in this deployment task...).
$ vim config/deploy/test.rb
#role :app, %w{deploy@localhost}
#role :web, %w{deploy@localhost}
#role :db, %w{deploy@localhost}
set :ssh_options, {
keys: %w(/home/deploy/.ssh/id_rsa),
forward_agent: true,
}
In this deployment, we will use the "AWS SDK for Ruby", so we will install the SDK in advance.
$ sudo gem install aws-sdk
Next, set the deployment content in 'config/deploy.rb'.
$ vim config/deploy.rb
# config valid only for Capistrano 3.1
lock '3.2.1'
# Loading the AWS SDK for Ruby
require 'aws-sdk'
# Configuring for the AWS SDK
AWS.config({
:access_key_id => '<AWSアカウントのACCESS key="" id="">',
:secret_access_key => '<AWSアカウントのSECRET access="" key="">',
:region=> 'ap-northeast-1', # the region where the EC2 Instance is created
})
# AMI image_id
# Amazon Linux AMI 2014.03.2 (HVM)
set :ami_image_id, 'ami-29dc9228'
# Number of Instances to Create
set :instance_count, 4
# Instance Type to Create
set :ec2_instance_type, 't2.micro'
# Create Availability Zones
set :availability_zones, [ 'ap-northeast-1a', 'ap-northeast-1c' ]
# Created subnet_id
set :subnet_ids, [ 'subnet-********', 'subnet-********' ]
# Delete Capistrano default tasks
framework_tasks = [:starting, :started, :updating, :updated, :publishing, :published, :finishing, :finished]
framework_tasks.each do |t|
Rake::Task["deploy:#{t}"].clear
end
Rake::Task[:deploy].clear
desc 'Launch an EC2 instance to each availability zone different'
task :launch do
run_locally do
ec2 = AWS::EC2.new
created_instances = []
cnt = 0
while cnt < fetch(:instance_count) do
if cnt.even? then
current_az = fetch(:availability_zones)[0]
current_sn = fetch(:subnet_ids)[0]
else
current_az = fetch(:availability_zones)[1]
current_sn = fetch(:subnet_ids)[1]
end
i = ec2.instances.create(
:image_id => fetch(:ami_image_id),
:availability_zone => current_az,
:subnet => current_sn,
:instance_type => fetch(:ec2_instance_type),
:count => 1
)
sleep 10 while i.status == :panding
created_instances < i.id
cnt += 1
end
execute "echo -n #{created_instances} > ~/CREATED_INSTANCES"
end
end
desc 'Check the activation status of new instances'
task :check do
created_instances_list = 'CREATED_INSTANCES'
run_locally do
ec2 = AWS::EC2.new
begin
if test "[ -f ~/#{created_instances_list} ]"
created_instances = capture("cd ~; cat #{created_instances_list}").chomp
ci = created_instances.gsub(/(\[|\s|\])/, '').split(',')
target_instances = ec2.instances.select { |i| i.exists? && i.status == :running && ci.include?( i.id) }.map(&:private_ip_address)
if target_instances.length == 0 then
raise "No created instances"
end
target_instances.each { |var|
server var, user: 'ec2-user', roles: %w{web app}
}
end
rescue => e
info e
exit
end
end
end
task :deploy => :check do
run_locally do
info roles(:all)
info 'Next task of deploy on new instances'
# deploy start
end
end
Actually launch the instance.
$ cap test launch
INFO[10af60ae] Running /usr/bin/env echo -n ["i-7497be72", "i-01c31718", "i-4d94bd4b", "i-00c31719"] > ~/CREATED_INSTANCES on localhost
DEBUG[10af60ae] Command: echo -n ["i-7497be72", "i-01c31718", "i-4d94bd4b", "i-00c31719"] > ~/CREATED_INSTANCES
INFO[10af60ae] Finished in 0.003 seconds with exit status 0 (successful).
The above log is output, and the instance launch seems to have been completed, so check it on the AWS management console.

Four instances were indeed launching in separate AvailabilityZones alternately. It is an ideal movement. Note that the launch time of AWS instances varies depending on the environment, so the above "launch" task is completed without checking the launch status of the EC2 instance. However, if this continues, the information of the instance will not be carried over when the next task of Capistorano is launched, so I write the ID of the instance launched in the "launch" task to a file called "CREATED_INSTANCES" and finish it. In the next task, I pick up the instance ID written in "CREATED_INSTANCES", check the startup status of the instance, and if the status is ":running", set it as the server to deploy. Also, in the "check" task, we get the private IP address of the new instance with the status ":running" and use it as the hostname of the deployed server, but if the new instance is assigned a public IP address and public DNS is set, we can change this to '{}.map(&:d ns_name)' It's okay to use it as a name.
Try to run the follow-up tasks.
$ cap test deploy
DEBUG[79c503fb] Running /usr/bin/env [ -f ~/CREATED_INSTANCES ] on localhost
DEBUG[79c503fb] Command: [ -f ~/CREATED_INSTANCES ]
DEBUG[79c503fb] Finished in 0.003 seconds with exit status 0 (successful).
DEBUG[9dd1f93d] Running /usr/bin/env cd ~; cat CREATED_INSTANCES on localhost
DEBUG[9dd1f93d] Command: cd ~; cat CREATED_INSTANCES
DEBUG[9dd1f93d] [i-7497be72, i-01c31718, i-4d94bd4b, i-00c31719]
DEBUG[9dd1f93d] Finished in 0.002 seconds with exit status 0 (successful).
INFO[#<Capistrano::Configuration::Server:0x0000000189a7c8 @user="ec2-user", @hostname="176.34.61.80", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x00000001899238 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a3a08 @user="ec2-user", @hostname="176.34.62.168", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018a3080 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a0d58 @user="ec2-user", @hostname="176.34.62.75", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018a6910 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a8ee0 @user="ec2-user", @hostname="176.34.61.75", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018b3818 @properties={}, @roles=#<Set: {:web,="" :app}="">>>]
INFONext task of deploy on new instances
The information of the instance created in the previous task was taken over and successfully set as the server to be deployed. In the next task (in this case, the "deploy" task), you can install Apache, PHP, or MySQL for each new instance, which will be fine and connected to the previous WordPress deployment.
In the end, you can create a dream-like deployment environment that allows you to create a server and deploy WordPress at once by simply entering Capistrano commands 2~3 times.
Reference Sites
- Rapid Study AWS to 2. Create EC2 with the AWS SDK for Ruby
- Acquire and deploy EC2 instances under ELB in Capistrano</AWSアカウントのSECRET></AWSアカウントのACCESS>