@Test public void testIncrementMinInstancesForAsgHappy() { String logicalId = "asg id"; String instanceId = "instance id"; int minSize = 2; when(autoScalingClient.describeAutoScalingGroups( new DescribeAutoScalingGroupsRequest().withAutoScalingGroupNames(logicalId)) ).thenReturn( new DescribeAutoScalingGroupsResult() .withAutoScalingGroups( new AutoScalingGroup().withInstances( new Instance().withInstanceId(instanceId)) .withMinSize(minSize) ) ); autoScalingService.updateMinInstancesForAutoScalingGroup(logicalId, minSize - 1); verify(autoScalingClient).updateAutoScalingGroup(new UpdateAutoScalingGroupRequest() .withAutoScalingGroupName(logicalId) .withMinSize(minSize - 1)); }
@Override public void execute(Context context) throws Exception { String key = "autoScaling/" + resource.id; context.output(key, String.format("status=%s, ami=%s", resource.status, resource.launchConfig.ami.id())); com.amazonaws.services.autoscaling.model.AutoScalingGroup remoteASGroup = resource.remoteASGroup; if (remoteASGroup != null) { context.output(key, String.format("name=%s, min=%s, desired=%s, max=%s, imageId=%s", remoteASGroup.getAutoScalingGroupName(), remoteASGroup.getMinSize(), remoteASGroup.getDesiredCapacity(), remoteASGroup.getMaxSize(), resource.launchConfig.remoteLaunchConfig.getImageId())); List<String> instanceIds = remoteASGroup.getInstances().stream().map(Instance::getInstanceId).collect(Collectors.toList()); if (!instanceIds.isEmpty()) { for (com.amazonaws.services.ec2.model.Instance remoteInstance : AWS.ec2.describeInstances(instanceIds)) { context.output(key, String.format("instanceId=%s, state=%s, privateDNS=%s, privateIP=%s", remoteInstance.getInstanceId(), remoteInstance.getState().getName(), remoteInstance.getPrivateDnsName(), remoteInstance.getPrivateIpAddress())); } } } }
public boolean checkInstanceInServiceOnAllElb(Instance newInstance, List<String> loadBalancerNames) { if (newInstance == null) { throw new IllegalStateException("Unable to check null instance"); } for (String elb : loadBalancerNames) { DescribeInstanceHealthResult result = awsElbClient.describeInstanceHealth(new DescribeInstanceHealthRequest(elb)); Optional<InstanceState> state = result.getInstanceStates().stream().filter(s -> s.getInstanceId().equals(newInstance.getInstanceId())).findFirst(); if (!state.isPresent()) { log.info("instance state for instance " + newInstance.getInstanceId() + " on elb " + elb + " is unknown"); return false; } log.info("instance state for instance " + newInstance.getInstanceId() + " on elb " + elb + " is " + state.get().getState()); if (!"InService".equals(state.get().getState())) { return false; } } return true; }
/** * Gets a list of EC2 Instance objects for a given auto scaling group name * @param groupName auto scaling group name * @return List of Instances containing instance IDs and availability zones */ public List<EC2Instance> getInstancesForAutoScalingGroup(String groupName) { List<Instance> instanceList = getAutoScalingGroup(groupName).getInstances(); return instanceList.stream().map(i -> new EC2Instance().withInstanceId(i.getInstanceId()) .withAvailabilityZone(i.getAvailabilityZone()) ).collect(Collectors.toList()); }
private List<String> listOldInstances() { asGroupName = resource.remoteASGroup.getAutoScalingGroupName(); List<Instance> oldInstances = resource.remoteASGroup.getInstances(); List<String> oldInstanceIds = oldInstances.stream().map(Instance::getInstanceId).collect(Collectors.toList()); logger.info("old instances => {}", oldInstanceIds); return oldInstanceIds; }
private List<String> waitUntilInstanceAttachedToASG() throws InterruptedException { List<String> newInstanceIds; while (true) { Threads.sleepRoughly(Duration.ofSeconds(30)); com.amazonaws.services.autoscaling.model.AutoScalingGroup remoteASGroup = AWS.as.describeASGroup(asGroupName); for (Instance instance : remoteASGroup.getInstances()) { logger.info("instance status, instanceId={}, lifecycle={}, health={}, new={}", instance.getInstanceId(), instance.getLifecycleState(), instance.getHealthStatus(), !oldInstanceIds.contains(instance.getInstanceId())); } long inServiceCount = remoteASGroup.getInstances().stream().filter(instance -> "InService".equals(instance.getLifecycleState())).count(); if (inServiceCount < remoteASGroup.getDesiredCapacity()) { logger.info("continue to wait, not all instances are ready, inService={}, desired={}", inServiceCount, remoteASGroup.getDesiredCapacity()); } else { logger.info("all instances of auto scaling group are in service"); newInstanceIds = remoteASGroup.getInstances().stream() .filter(instance -> !oldInstanceIds.contains(instance.getInstanceId())) .map(Instance::getInstanceId) .collect(Collectors.toList()); break; } } return newInstanceIds; }
@Override public void execute(Context context) throws Exception { logger.info("upload package dir, asGroupId={}", resource.id); List<String> instanceIds = resource.remoteASGroup.getInstances().stream() .map(Instance::getInstanceId) .collect(Collectors.toList()); List<com.amazonaws.services.ec2.model.Instance> remoteInstances = AWS.ec2.describeInstances(instanceIds); LinuxUploader uploader = new LinuxUploader(context.env, remoteInstances, context); uploader.upload(); }
@Override public void execute(Context context) throws Exception { logger.info("execute command, asGroupId={}", resource.id); List<String> instanceIds = resource.remoteASGroup.getInstances().stream().map(Instance::getInstanceId).collect(Collectors.toList()); List<com.amazonaws.services.ec2.model.Instance> remoteInstances = AWS.ec2.describeInstances(instanceIds); LinuxCommandRunner runner = new LinuxCommandRunner(context.env, remoteInstances, context); runner.run(); }
@Override public Map<String, List<String>> getRacMembership(Collection<String> autoScalingGroupNames) { if (CollectionUtils.isEmpty(autoScalingGroupNames)) { return Collections.emptyMap(); } AmazonAutoScaling client = null; try { client = getAutoScalingClient(); DescribeAutoScalingGroupsRequest describeAutoScalingGroupsRequest = new DescribeAutoScalingGroupsRequest().withAutoScalingGroupNames(autoScalingGroupNames); DescribeAutoScalingGroupsResult describeAutoScalingGroupsResult = client.describeAutoScalingGroups(describeAutoScalingGroupsRequest); Map<String, List<String>> asgs = new HashMap<>(); for (AutoScalingGroup autoScalingGroup : describeAutoScalingGroupsResult.getAutoScalingGroups()) { List<String> asgInstanceIds = Lists.newArrayList(); for (Instance asgInstance : autoScalingGroup.getInstances()) { if (!(asgInstance.getLifecycleState().equalsIgnoreCase("terminating") || asgInstance.getLifecycleState().equalsIgnoreCase("shutting-down") || asgInstance.getLifecycleState().equalsIgnoreCase("terminated"))) { asgInstanceIds.add(asgInstance.getInstanceId()); } } asgs.put(autoScalingGroup.getAutoScalingGroupName(), asgInstanceIds); logger.info("AWS returned the following instance ID's for {} ASG: {}", autoScalingGroup.getAutoScalingGroupName(), StringUtils.join(asgInstanceIds, ",")); } return asgs; } finally { if (client != null) { client.shutdown(); } } }
public static AutoScalingGroup group(String name, LaunchConfiguration launchConfig, int desiredCapacity, Collection<com.amazonaws.services.ec2.model.Instance> ec2Instances) { AutoScalingGroup autoScalingGroup = new AutoScalingGroup().withAutoScalingGroupName(name) .withLaunchConfigurationName(launchConfig.getLaunchConfigurationName()) .withDesiredCapacity(desiredCapacity).withInstances(toAsInstances(ec2Instances)); return autoScalingGroup; }
public static Collection<Instance> toAsInstances( Collection<com.amazonaws.services.ec2.model.Instance> ec2Instances) { List<Instance> asInstances = new ArrayList<>(); for (com.amazonaws.services.ec2.model.Instance ec2Instance : ec2Instances) { Instance asInstance = new Instance().withInstanceId(ec2Instance.getInstanceId()) .withLifecycleState(ec2StateToLifecycleState(ec2Instance.getState())); asInstances.add(asInstance); } return asInstances; }
public List<String> getInstanceIds(AmazonAutoScalingClient amazonASClient, String asGroupName) { DescribeAutoScalingGroupsResult describeAutoScalingGroupsResult = amazonASClient .describeAutoScalingGroups(new DescribeAutoScalingGroupsRequest().withAutoScalingGroupNames(asGroupName)); List<String> instanceIds = new ArrayList<>(); if (describeAutoScalingGroupsResult.getAutoScalingGroups().get(0).getInstances() != null) { for (Instance instance : describeAutoScalingGroupsResult.getAutoScalingGroups().get(0).getInstances()) { if ("InService".equals(instance.getLifecycleState())) { instanceIds.add(instance.getInstanceId()); } } } return instanceIds; }
public List<Ec2Instance> getInstancesForAutoScalingGroup(Log log, AutoScalingGroup autoScalingGroup) throws MojoFailureException { log.info("retrieving list of instanceId's for auto scaling group with id : " + activeConfiguration.getAutoScalingGroupId()); activeConfiguration.getHosts().clear(); log.debug("describing instances in auto scaling group"); if (autoScalingGroup.getInstances().isEmpty()) { return new ArrayList<>(); } Map<String, Instance> instanceMap = autoScalingGroup.getInstances().stream().collect(Collectors.toMap(Instance::getInstanceId, Function.identity())); try { DescribeInstancesResult instancesResult = awsEc2Client.describeInstances(new DescribeInstancesRequest().withInstanceIds(autoScalingGroup.getInstances().stream().map(Instance::getInstanceId).collect(Collectors.toList()))); List<Ec2Instance> ec2Instances = instancesResult.getReservations().stream().flatMap(r -> r.getInstances().stream()).map(this::toEc2Instance).collect(Collectors.toList()); log.debug("describing elb status"); autoScalingGroup.getLoadBalancerNames().forEach(elb -> this.updateInstancesStateOnLoadBalancer(elb, ec2Instances)); ec2Instances.forEach(i -> i.updateAsState(AwsState.map(instanceMap.get(i.getInstanceId()).getLifecycleState()))); ec2Instances.sort((o1, o2) -> { int sComp = o1.getAsState().compareTo(o2.getAsState()); if (sComp != 0) { return sComp; } else { return o1.getElbState().compareTo(o2.getElbState()); } }); if (activeConfiguration.isIgnoreInStandby()) { return ec2Instances.stream().filter(i -> i.getAsState() != AwsState.STANDBY).collect(Collectors.toList()); } return ec2Instances; } catch (AmazonClientException e) { log.error(e.getMessage(), e); throw new MojoFailureException(e.getMessage()); } }
public boolean checkEc2Instance(String instanceId) { boolean instanceTerminated = false; try { DescribeInstancesResult result = awsEc2Client.describeInstances(new DescribeInstancesRequest().withInstanceIds(instanceId)); List<com.amazonaws.services.ec2.model.Instance> instances = result.getReservations().stream() .flatMap(r -> r.getInstances().stream()) .filter(i -> i.getInstanceId().equals(instanceId)) .collect(Collectors.toList()); instanceTerminated = instances.isEmpty() || instances.stream() .map(com.amazonaws.services.ec2.model.Instance::getState) .anyMatch(s -> s.getCode().equals(48)); } catch (AmazonServiceException e) { log.info(e.toString(), e); if (e.getStatusCode() == 400) { instanceTerminated = true; } } if (instanceTerminated) { log.warn("Invalid instance " + instanceId + " in group " + activeConfiguration.getAutoScalingGroupId() + ". Detaching instance."); awsAsClient.detachInstances(new DetachInstancesRequest() .withAutoScalingGroupName(activeConfiguration.getAutoScalingGroupId()) .withInstanceIds(instanceId) .withShouldDecrementDesiredCapacity(false)); } return instanceTerminated; }
private List<Ec2Instance> checkInstances(AwsAutoScalingDeployUtils awsDeployUtils, AutoScalingGroup asGroup, List<Ec2Instance> instances) { List<String> removedInstances = asGroup.getInstances().stream() .filter(i -> i.getLifecycleState().equalsIgnoreCase(AwsState.STANDBY.name())) .map(Instance::getInstanceId) .filter(awsDeployUtils::checkEc2Instance) .collect(Collectors.toList()); if (removedInstances != null && removedInstances.isEmpty()) { return instances.stream() .filter(i -> !removedInstances.contains(i.getInstanceId())) .collect(Collectors.toList()); } return instances; }
@Test public void testGetPublicDnsForAutoScalingGroup() { String logicalId = "fake-logical-id"; String instanceId = "fake-instance-id"; String dnsName = "dns.name"; when(autoScalingClient.describeAutoScalingGroups( new DescribeAutoScalingGroupsRequest() .withAutoScalingGroupNames(logicalId) ) ).thenReturn( new DescribeAutoScalingGroupsResult() .withAutoScalingGroups( new AutoScalingGroup() .withInstances( new Instance() .withInstanceId(instanceId) ) ) ); when(ec2Client.describeInstances( new DescribeInstancesRequest() .withInstanceIds(instanceId) ) ).thenReturn( new DescribeInstancesResult() .withReservations( new Reservation() .withInstances( new com.amazonaws.services.ec2.model.Instance() .withPublicDnsName(dnsName) ) ) ); // invoke method under test List<String> results = autoScalingService.getPublicDnsForAutoScalingGroup(logicalId); assertEquals(1, results.size()); assertEquals(dnsName, results.get(0)); }
public static Collection<Instance> asInstances(Instance... instances) { return new ArrayList<>(Arrays.asList(instances)); }
public static List<com.amazonaws.services.ec2.model.Instance> ec2Instances( com.amazonaws.services.ec2.model.Instance... instances) { return new ArrayList<>(Arrays.asList(instances)); }
public static com.amazonaws.services.ec2.model.Instance ec2Instance(String id, String state) { return new com.amazonaws.services.ec2.model.Instance().withInstanceId(id) .withInstanceType(InstanceType.M1Medium).withState(new InstanceState().withName(state)); }
public static com.amazonaws.services.ec2.model.Instance spotInstance(String spotId, String instanceId, String state) { return new com.amazonaws.services.ec2.model.Instance().withInstanceId(instanceId) .withInstanceType(InstanceType.M1Medium).withState(new InstanceState().withName(state)) .withSpotInstanceRequestId(spotId); }
private Ec2Instance toEc2Instance(com.amazonaws.services.ec2.model.Instance instance) { return new Ec2Instance.Builder().withInstanceId(instance.getInstanceId()).withPrivateIp(instance.getPrivateIpAddress()).withPublicIp(instance.getPublicIpAddress()).build(); }
private Instance findNewInstance(AutoScalingGroup originalGroup, AutoScalingGroup updatedGroup) { updatedGroup.getInstances().removeAll(originalGroup.getInstances()); return updatedGroup.getInstances().isEmpty() ? null : updatedGroup.getInstances().get(0); }
public boolean executeRequest(final AutoScalingGroup autoScalingGroup, AwsAutoScalingDeployUtils awsDeployUtils, InstanceStatus instanceStatus) { final AtomicInteger waitFor = new AtomicInteger(1); final AtomicBoolean inService = new AtomicBoolean(false); final AtomicBoolean found = new AtomicBoolean(false); log.info("Waiting for new instance in asGroup to come in service..."); ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.scheduleAtFixedRate(() -> { log.debug("existing instances : " + Arrays.toString(autoScalingGroup.getInstances().stream().map(Instance::getInstanceId).toArray())); AutoScalingGroup updatedGroup = awsDeployUtils.getAutoScalingGroup(); log.debug("Updated instances : " + Arrays.toString(updatedGroup.getInstances().stream().map(Instance::getInstanceId).toArray())); if (updatedGroup.getInstances().equals(autoScalingGroup.getInstances())) { log.info("no new instance found in auto scaling group."); } if (newInstance == null) { newInstance = findNewInstance(autoScalingGroup, updatedGroup); if (newInstance != null && !found.get()) { found.set(true); log.info("Found new instance with id " + newInstance.getInstanceId()); } } if (newInstance != null && instanceStatus.inService(newInstance)) { waitFor.decrementAndGet(); } }, 30, 30, TimeUnit.SECONDS); try { while (waitFor.intValue() > 0 && System.currentTimeMillis() <= timeout) { Thread.sleep(3000); } log.info("Shutting down executor"); exec.shutdown(); log.info("awaiting termination of executor"); exec.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { log.error(e.getMessage()); Thread.currentThread().interrupt(); inService.get(); } catch (Exception t) { log.error("Throwable: ", t); } return inService.get(); }
/** * Gets a list of EC2 instance IDs for a given auto scaling group name * @param groupName auto scaling group name * @return List of strings containing instance IDs */ public List<String> getInstanceIdsForAutoScalingGroup(String groupName) { List<Instance> instanceList = getAutoScalingGroup(groupName).getInstances(); return instanceList.stream().map(i -> i.getInstanceId()).collect(Collectors.toList()); }
Boolean inService(Instance newInstance);