lserman / capistrano-elbas

Deploy Rails apps to AWS AutoScale groups
MIT License
96 stars 67 forks source link

InstanceCollection only returns one instance, despite multiple running instances #31

Closed kragej closed 5 years ago

kragej commented 5 years ago

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