Skip to content

Commit

Permalink
Fixing EC2 launch type and Windows provisioning. Upgrading to use EC2…
Browse files Browse the repository at this point in the history
… Launch Templates and also

support EC2 for Linux workloads (still hard coded to use Fargate for
Linux).
  • Loading branch information
brtrvn committed Apr 7, 2022
1 parent 3822fc1 commit 5df2843
Show file tree
Hide file tree
Showing 18 changed files with 394 additions and 296 deletions.
9 changes: 8 additions & 1 deletion resources/custom-resources/set-instance-protection/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ limitations under the License.
</license>
</licenses>
<properties>
<checkstyle.maxAllowedViolations>4</checkstyle.maxAllowedViolations>
<checkstyle.maxAllowedViolations>0</checkstyle.maxAllowedViolations>
</properties>

<build>
Expand Down Expand Up @@ -88,6 +88,13 @@ limitations under the License.
<!-- Don't bundle our layer so we get the shared one at runtime -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.amazon.aws.partners.saasfactory.saasboost</groupId>
<artifactId>CloudFormationUtils</artifactId>
<version>1.0.0</version>
<!-- Don't bundle our layer so we get the shared one at runtime -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>autoscaling</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,11 @@

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.services.autoscaling.AutoScalingClient;
import software.amazon.awssdk.services.autoscaling.model.*;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.concurrent.*;

Expand All @@ -38,10 +32,8 @@ public class SetInstanceProtection implements RequestHandler<Map<String, Object>
private final AutoScalingClient autoScaling;

public SetInstanceProtection() {
long startTimeMillis = System.currentTimeMillis();
LOGGER.info("Version Info: {}", Utils.version(this.getClass()));
autoScaling = Utils.sdkClient(AutoScalingClient.builder(), AutoScalingClient.SERVICE_NAME);
LOGGER.info("Constructor init: {}", System.currentTimeMillis() - startTimeMillis);
}

@Override
Expand All @@ -53,8 +45,9 @@ public Object handleRequest(Map<String, Object> event, Context context) {
final String autoScalingGroup = (String) resourceProperties.get("AutoScalingGroup");
final Boolean enableInstanceProtection = Boolean.valueOf((String) resourceProperties.get("Enable"));
ExecutorService service = Executors.newSingleThreadExecutor();
ObjectNode responseData = JsonNodeFactory.instance.objectNode();
LOGGER.info("Setting instance protection to {} for Autoscaling group {}", enableInstanceProtection, autoScalingGroup);
Map<String, Object> responseData = new HashMap<>();
LOGGER.info("Setting instance protection to {} for Autoscaling group {}", enableInstanceProtection,
autoScalingGroup);
try {
Runnable r = () -> {
if ("Delete".equalsIgnoreCase(requestType) || "Update".equalsIgnoreCase(requestType)) {
Expand All @@ -64,7 +57,8 @@ public Object handleRequest(Map<String, Object> event, Context context) {
request.autoScalingGroupNames(autoScalingGroup)
);
if (response.hasAutoScalingGroups()) {
LOGGER.info("Auto scaling found {} groups for {}", response.autoScalingGroups().size(), autoScalingGroup);
LOGGER.info("AutoScaling found {} groups for {}", response.autoScalingGroups().size(),
autoScalingGroup);
if (!response.autoScalingGroups().isEmpty()) {
AutoScalingGroup asgGroup = response.autoScalingGroups().get(0);
List<String> instancesToUpdate = new ArrayList<>();
Expand All @@ -75,32 +69,34 @@ public Object handleRequest(Map<String, Object> event, Context context) {
.protectedFromScaleIn(enableInstanceProtection)
.autoScalingGroupName(autoScalingGroup)
);
LOGGER.info("Disabled instance protection on {} instances.", instancesToUpdate.size());
LOGGER.info("{} instance protection on {} instances.",
((enableInstanceProtection) ? "Enabled" : "Disabled"),
instancesToUpdate.size()
);
CloudFormationResponse.send(event, context, "SUCCESS", responseData);
} catch (AutoScalingException e) {
LOGGER.error("autoscaling:SetInstanceProtection error", e);
LOGGER.error(Utils.getFullStackTrace(e));
responseData.put("Reason", "Error " + e.getMessage());
sendResponse(event, context, "FAILED", responseData);
responseData.put("Reason", e.getMessage());
CloudFormationResponse.send(event, context, "FAILED", responseData);
}
} else {
LOGGER.info("No auto scaling groups matched.");
}
}
} catch (AutoScalingException e) {
LOGGER.error("DisableInstanceProtection::Error " + e.getMessage());
LOGGER.error("autoscaling:describeAutoScalingGroups error", e);
LOGGER.error(Utils.getFullStackTrace(e));
responseData.put("Reason", "Error " + e.getMessage());
sendResponse(event, context, "FAILED", responseData);
responseData.put("Reason", e.getMessage());
CloudFormationResponse.send(event, context, "FAILED", responseData);
}
LOGGER.info("responseDate: " + Utils.toJson(responseData));
sendResponse(event, context, "SUCCESS", responseData);
} else if ("Create".equalsIgnoreCase(requestType)) {
LOGGER.info("CREATE");
sendResponse(event, context, "SUCCESS", responseData);
CloudFormationResponse.send(event, context, "SUCCESS", responseData);
} else {
LOGGER.error("FAILED unknown requestType " + requestType);
LOGGER.error("FAILED unknown requestType {}", requestType);
responseData.put("Reason", "Unknown RequestType " + requestType);
sendResponse(event, context, "FAILED", responseData);
CloudFormationResponse.send(event, context, "FAILED", responseData);
}
};
Future<?> f = service.submit(r);
Expand All @@ -111,52 +107,11 @@ public Object handleRequest(Map<String, Object> event, Context context) {
String stackTrace = Utils.getFullStackTrace(e);
LOGGER.error(stackTrace);
responseData.put("Reason", stackTrace);
sendResponse(event, context, "FAILED", responseData);
CloudFormationResponse.send(event, context, "FAILED", responseData);
} finally {
service.shutdown();
}
return null;
}

public final Object sendResponse(final Map<String, Object> event, final Context context, final String responseStatus, ObjectNode responseData) {
String responseUrl = (String) event.get("ResponseURL");
LOGGER.info("ResponseURL: {}", responseUrl);

try {
URL url = new URL(responseUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "");
connection.setRequestMethod("PUT");

ObjectNode responseBody = JsonNodeFactory.instance.objectNode();
responseBody.put("Status", responseStatus);
responseBody.put("RequestId", (String) event.get("RequestId"));
responseBody.put("LogicalResourceId", (String) event.get("LogicalResourceId"));
responseBody.put("StackId", (String) event.get("StackId"));
responseBody.put("PhysicalResourceId", (String) event.get("LogicalResourceId"));
if (!"FAILED".equals(responseStatus)) {
responseBody.set("Data", responseData);
} else {
responseBody.put("Reason", responseData.get("Reason").asText());
}
LOGGER.info("Response Body: " + responseBody.toString());

try (OutputStreamWriter response = new OutputStreamWriter(connection.getOutputStream())) {
response.write(responseBody.toString());
} catch (IOException ioe) {
LOGGER.error("Failed to call back to CFN response URL");
LOGGER.error(Utils.getFullStackTrace(ioe));
}

LOGGER.info("Response Code: {}", connection.getResponseCode());
connection.disconnect();
} catch (IOException e) {
LOGGER.error("Failed to open connection to CFN response URL");
LOGGER.error(Utils.getFullStackTrace(e));
}

return null;
}

}
48 changes: 32 additions & 16 deletions resources/saas-boost-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Resources:
- Effect: Allow
Action:
- sts:AssumeRole
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
Resource: !GetAtt SaaSBoostSystemRole.Arn
WorkloadDeployLambda:
Type: AWS::Lambda::Function
DependsOn: WorkloadDeployLogs
Expand All @@ -154,10 +154,11 @@ Resources:
Environment:
Variables:
SAAS_BOOST_ENV: !Ref Environment
API_TRUST_ROLE: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
API_TRUST_ROLE: !GetAtt SaaSBoostSystemRole.Arn
API_GATEWAY_HOST: !Sub ${SaaSBoostPrivateApi}.execute-api.${AWS::Region}.amazonaws.com
API_GATEWAY_STAGE: !Ref PrivateApiStage
CODE_PIPELINE_BUCKET: !Ref CodePipelineBucket
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -257,6 +258,7 @@ Resources:
Variables:
SAAS_BOOST_ENV: !Ref Environment
SAAS_BOOST_EVENT_BUS: !Sub '{{resolve:ssm:/saas-boost/${Environment}/EVENT_BUS}}'
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -314,6 +316,7 @@ Resources:
Variables:
SAAS_BOOST_ENV: !Ref Environment
SAAS_BOOST_EVENT_BUS: !Sub '{{resolve:ssm:/saas-boost/${Environment}/EVENT_BUS}}'
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -469,6 +472,9 @@ Resources:
S3Key: !Sub ${LambdaSourceFolder}/EcsServiceUpdate-lambda.zip
Layers:
- !Ref SaaSBoostUtilsLayer
Environment:
Variables:
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -496,7 +502,7 @@ Resources:
- SaaSBoostPublicApi
- SaaSBoostPrivateApi
Properties:
RoleName: !Sub sb-private-api-trust-role-${Environment}-${AWS::Region}
RoleName: !Sub sb-${Environment}-private-api-trust-role-${AWS::Region}
Path: '/'
AssumeRolePolicyDocument:
Version: 2012-10-17
Expand All @@ -507,7 +513,7 @@ Resources:
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub sb-private-api-trust-policy-${Environment}-${AWS::Region}
- PolicyName: !Sub sb-${Environment}-private-api-trust-policy-${AWS::Region}
PolicyDocument:
Version: 2012-10-17
Statement:
Expand All @@ -517,10 +523,16 @@ Resources:
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SaaSBoostPrivateApi}/*/*/*
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SaaSBoostPublicApi}/*/*/*
SSMParamPrivateApiRole:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub /saas-boost/${Environment}/PRIVATE_API_TRUST_ROLE
Type: String
Value: !GetAtt SaaSBoostSystemRole.Arn
SystemRestClientExecRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub sb-private-api-client-role-${Environment}-${AWS::Region}
RoleName: !Sub sb-${Environment}-private-api-client-role-${AWS::Region}
Path: '/'
AssumeRolePolicyDocument:
Version: 2012-10-17
Expand All @@ -532,7 +544,7 @@ Resources:
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub sb-private-api-client-policy-${Environment}-${AWS::Region}
- PolicyName: !Sub sb-${Environment}-private-api-client-policy-${AWS::Region}
PolicyDocument:
Version: 2012-10-17
Statement:
Expand All @@ -550,7 +562,7 @@ Resources:
- Effect: Allow
Action:
- sts:AssumeRole
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
Resource: !GetAtt SaaSBoostSystemRole.Arn
SystemRestApiClientLogs:
Type: AWS::Logs::LogGroup
Properties:
Expand All @@ -574,9 +586,10 @@ Resources:
Environment:
Variables:
SAAS_BOOST_ENV: !Ref Environment
API_TRUST_ROLE: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
API_TRUST_ROLE: !GetAtt SaaSBoostSystemRole.Arn
API_GATEWAY_HOST: !Sub ${SaaSBoostPrivateApi}.execute-api.${AWS::Region}.amazonaws.com
API_GATEWAY_STAGE: !Ref PrivateApiStage
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -644,7 +657,7 @@ Resources:
- Effect: Allow
Action:
- sts:AssumeRole
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
Resource: !GetAtt SaaSBoostSystemRole.Arn
EcsShutdownServicesLogs:
Type: AWS::Logs::LogGroup
Properties:
Expand All @@ -669,9 +682,10 @@ Resources:
Environment:
Variables:
SAAS_BOOST_ENV: !Ref Environment
API_TRUST_ROLE: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
API_TRUST_ROLE: !GetAtt SaaSBoostSystemRole.Arn
API_GATEWAY_HOST: !Sub ${SaaSBoostPrivateApi}.execute-api.${AWS::Region}.amazonaws.com
API_GATEWAY_STAGE: !Ref PrivateApiStage
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -720,7 +734,7 @@ Resources:
- Effect: Allow
Action:
- sts:AssumeRole
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
Resource: !GetAtt SaaSBoostSystemRole.Arn
EcsStartupServicesLogs:
Type: AWS::Logs::LogGroup
Properties:
Expand All @@ -745,9 +759,10 @@ Resources:
Environment:
Variables:
SAAS_BOOST_ENV: !Ref Environment
API_TRUST_ROLE: !Sub arn:aws:iam::${AWS::AccountId}:role/sb-private-api-trust-role-${Environment}-${AWS::Region}
API_TRUST_ROLE: !GetAtt SaaSBoostSystemRole.Arn
API_GATEWAY_HOST: !Sub ${SaaSBoostPrivateApi}.execute-api.${AWS::Region}.amazonaws.com
API_GATEWAY_STAGE: !Ref PrivateApiStage
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand Down Expand Up @@ -794,7 +809,7 @@ Resources:
- Effect: Allow
Action:
- autoscaling:SetInstanceProtection
Resource: !Sub arn:aws:autoscaling:${AWS::Region}:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/tenant-*
Resource: !Sub arn:aws:autoscaling:${AWS::Region}:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/sb-${Environment}-tenant-*
SetInstanceProtectionLogs:
Type: AWS::Logs::LogGroup
Properties:
Expand All @@ -816,6 +831,10 @@ Resources:
S3Key: !Sub ${LambdaSourceFolder}/SetInstanceProtection-lambda.zip
Layers:
- !Ref SaaSBoostUtilsLayer
- !Ref CloudFormationUtilsLayer
Environment:
Variables:
JAVA_TOOL_OPTIONS: '-XX:+TieredCompilation -XX:TieredStopAtLevel=1'
Tags:
- Key: "Application"
Value: "SaaSBoost"
Expand All @@ -826,9 +845,6 @@ Resources:
# Macro transform will add as many AWS::ECR::Repository resources as necessary
# based on the length of the list of ApplicationServices passed as a parameter
Outputs:
CodePipelineIamRole:
Description: SaaS Boost tenant deploy CodePipeline IAM role
Value: !GetAtt TenantCodePipelineRole.Arn
SaaSBoostPublicApi:
Description: SaaS Boost Public API
Value: !Ref SaaSBoostPublicApi
Expand Down
Loading

0 comments on commit 5df2843

Please sign in to comment.