I am trying to deploy multiple EC2 instances via bastion host. I put my EC2 instances under ELB and always access via bastion.
require 'aws-sdk'
require 'net/ssh/proxy/command'
ec2 = Aws::EC2::Client.new(region: fetch(:aws_region))
ec2_filtered = ec2.describe_instances(
filters:[
{name: "tag:env", values: [fetch(:rails_env)]},
{name: "tag:role", values: [fetch(:aws_tag_role)]},
{name: 'instance-state-name', values: ['running']}
])
instances = ec2_filtered.reservations.map(&:instances)[0].map(&:private_ip_address)
instances = ec2_filtered.reservations.map(&:instances)[1].map(&:private_ip_address)
set :branch, 'master'
role :app, *instances
role :web, *instances
role :db, [instances.first]
server *instances,
user: fetch(:deploy_user),
ssh_options: {
forward_agent: true,
keys: fetch(:deploy_ssh_keys),
proxy: Net::SSH::Proxy::Command::new('ssh bastion.mamorio -W %h:%p')
}
The code above works but it's really redundant and I want to get the whole "private ip" at once.
I tried this code:
instances = ec2_filtered.reservations.map(&:instances).flatten.map(&:private_ip_address)
but I get the following error.
NoMethodError: undefined method `merge' for "10.0.xx.2xx":String
Any advice?
I think the problem is the value you are passing to Capistrano's role
declaration.
role :app, *instances
The role
method expects an array as the second argument, but in your example you are "splatting" the instances
array into separate arguments.
Try this instead:
role :app, instances
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.