Skip to content

Commit

Permalink
feat(ecs): Copy scaling policies from source server group
Browse files Browse the repository at this point in the history
When copying scaling alarms and target tracking policies, update the dimensions with the latest ECS cluster and service name

This removes the option to configure ECS scaling alarms in the 'autoscalingPolicies' parameter, which never worked anyway
  • Loading branch information
clareliguori committed Dec 20, 2018
1 parent 12c9dd8 commit 9313864
Show file tree
Hide file tree
Showing 8 changed files with 656 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public class CreateServerGroupDescription extends AbstractECSDescription {

Map<String, List<String>> availabilityZones;

List<MetricAlarm> autoscalingPolicies;
boolean copySourceScalingPoliciesAndActions = true;
Source source = new Source();

List<PlacementStrategy> placementStrategySequence;
String networkMode;
String subnetType;
Expand All @@ -66,4 +68,13 @@ public String getRegion() {
//CreateServerGroupDescription does not contain a region. Instead it has AvailabilityZones
return getAvailabilityZones().keySet().iterator().next();
}

@Data
@EqualsAndHashCode(callSuper = false)
public static class Source {
String account;
String region;
String asgName;
Boolean useSourceCapacity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScaling;
import com.amazonaws.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;
import com.amazonaws.services.cloudwatch.model.MetricAlarm;
import com.amazonaws.services.applicationautoscaling.model.*;
import com.amazonaws.services.ecs.AmazonECS;
import com.amazonaws.services.ecs.model.*;
import com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancing;
Expand All @@ -47,13 +44,7 @@
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

public class CreateServerGroupAtomicOperation extends AbstractEcsAtomicOperation<CreateServerGroupDescription, DeploymentResult> {
Expand Down Expand Up @@ -96,6 +87,8 @@ public DeploymentResult operate(List priorOutputs) {
String newServerGroupName = serverGroupNameResolver.resolveNextServerGroupName(description.getApplication(),
description.getStack(), description.getFreeFormDetails(), false);

ScalableTarget sourceTarget = getSourceScalableTarget();

String ecsServiceRole = inferAssumedRoleArn(credentials);

updateTaskStatus("Creating Amazon ECS Task Definition...");
Expand All @@ -106,11 +99,19 @@ public DeploymentResult operate(List priorOutputs) {

String resourceId = registerAutoScalingGroup(credentials, service);

if (!description.getAutoscalingPolicies().isEmpty()) {
List<String> alarmNames = description.getAutoscalingPolicies().stream()
.map(MetricAlarm::getAlarmName)
.collect(Collectors.toList());
ecsCloudMetricService.associateAsgWithMetrics(description.getCredentialAccount(), getRegion(), alarmNames, service.getServiceName(), resourceId);
if (description.isCopySourceScalingPoliciesAndActions() && sourceTarget != null) {
updateTaskStatus("Copying scaling policies...");
ecsCloudMetricService.copyScalingPolicies(
description.getCredentialAccount(),
getRegion(),
service.getServiceName(),
resourceId,
description.getSource().getAccount(),
description.getSource().getRegion(),
description.getSource().getAsgName(),
sourceTarget.getResourceId(),
description.getEcsClusterName());
updateTaskStatus("Done copying scaling policies...");
}

return makeDeploymentResult(service);
Expand Down Expand Up @@ -308,6 +309,30 @@ private String registerAutoScalingGroup(AmazonCredentials credentials,
return request.getResourceId();
}

private ScalableTarget getSourceScalableTarget() {
if (description.getSource() != null
&& description.getSource().getRegion() != null
&& description.getSource().getAccount() != null
&& description.getSource().getAsgName() != null) {

AWSApplicationAutoScaling autoScalingClient = getSourceAmazonApplicationAutoScalingClient();

DescribeScalableTargetsRequest request = new DescribeScalableTargetsRequest()
.withServiceNamespace(ServiceNamespace.Ecs)
.withScalableDimension(ScalableDimension.EcsServiceDesiredCount)
.withResourceIds(String.format("service/%s/%s", description.getEcsClusterName(), description.getSource().getAsgName()));

DescribeScalableTargetsResult result = autoScalingClient.describeScalableTargets(request);
if (result.getScalableTargets() != null && !result.getScalableTargets().isEmpty()) {
return result.getScalableTargets().get(0);
}

return null;
}

return null;
}

private String inferAssumedRoleArn(AmazonCredentials credentials) {
String role;
if (credentials instanceof AssumeRoleAmazonCredentials) {
Expand Down Expand Up @@ -377,6 +402,12 @@ private LoadBalancer retrieveLoadBalancer(String containerName) {
return loadBalancer;
}

private AWSApplicationAutoScaling getSourceAmazonApplicationAutoScalingClient() {
String sourceRegion = description.getSource().getRegion();
NetflixAmazonCredentials sourceCredentials = (NetflixAmazonCredentials)accountCredentialsProvider.getCredentials(description.getSource().getAccount());
return amazonClientProvider.getAmazonApplicationAutoScaling(sourceCredentials, sourceRegion, false);
}

private AWSApplicationAutoScaling getAmazonApplicationAutoScalingClient() {
AWSCredentialsProvider credentialsProvider = getCredentials().getCredentialsProvider();
NetflixAmazonCredentials credentialAccount = description.getCredentials();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ public void validate(List priorDescriptions, Object description, Errors errors)
rejectValue(errors, "placementStrategySequence", "not.nullable");
}

if (createServerGroupDescription.getAutoscalingPolicies() == null) {
rejectValue(errors, "autoscalingPolicies", "not.nullable");
}

if (createServerGroupDescription.getApplication() == null) {
rejectValue(errors, "application", "not.nullable");
}
Expand Down
Loading

0 comments on commit 9313864

Please sign in to comment.