module SimpleDeploy class AWS class InstanceReader include Helpers def initialize @config = SimpleDeploy.config @asg_connect = Fog::AWS::AutoScaling.new connection_args @ec2_connect = Fog::Compute::AWS.new connection_args end def list_stack_instances(stack_name) instances = [] #Nested stack nested_stacks = nested_stacks_names(stack_name) instances = nested_stacks.map {|stack| list_stack_instances stack }.flatten if nested_stacks.any? #Auto Scaling Group asg_ids = auto_scaling_group_id(stack_name) asg_instances = asg_ids.map { |asg_id| list_instances asg_id }.flatten #EC2 instance stack_instances = instance_names(stack_name) instances += (describe_instances (asg_instances + stack_instances)) if (asg_instances + stack_instances).any? instances end private def list_instances(asg_id) body = @asg_connect.describe_auto_scaling_groups('AutoScalingGroupNames' => [asg_id]).body result = body['DescribeAutoScalingGroupsResult']['AutoScalingGroups'].last return [] unless result result['Instances'].map { |info| info['InstanceId'] } end def describe_instances(instances) @ec2_connect.describe_instances('instance-state-name' => 'running', 'instance-id' => instances).body['reservationSet'] end def cloud_formation @cloud_formation ||= AWS::CloudFormation.new end def auto_scaling_group_id(stack_name) cf_stack_resources = cloud_formation.stack_resources stack_name parse_cf_stack_resources cf_stack_resources end def parse_cf_stack_resources(cf_stack_resources) asgs = cf_stack_resources.select do |r| r['ResourceType'] == 'AWS::AutoScaling::AutoScalingGroup' end asgs.any? ? asgs.map {|asg| asg['PhysicalResourceId'] } : [] end def nested_stacks_names(stack_name) cf_stack_resources = cloud_formation.stack_resources stack_name asgs = cf_stack_resources.select do |r| r['ResourceType'] == 'AWS::CloudFormation::Stack' && cloud_formation.stack_status(r['PhysicalResourceId']) != 'DELETE_COMPLETE' end asgs.any? ? asgs.map {|asg| asg['PhysicalResourceId'] } : [] end def instance_names(stack_name) cf_stack_resources = cloud_formation.stack_resources stack_name asgs = cf_stack_resources.select do |r| r['ResourceType'] == 'AWS::EC2::Instance' end asgs.any? ? asgs.map {|asg| asg['PhysicalResourceId'] } : [] end end end end