Skip to content

Commit

Permalink
feat(riff-raff.yaml): Add minInstancesInServiceParameters when appl…
Browse files Browse the repository at this point in the history
…icable
  • Loading branch information
akash1810 committed Oct 21, 2024
1 parent 632ff25 commit c0bee66
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/experimental/patterns/ec2-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class AutoScalingRollingUpdateTimeout implements IAspect {
*/
export class HorizontallyScalingDeploymentPropertiesExperimental implements IAspect {
public readonly stack: GuStack;
private readonly asgToParamMap: Map<string, CfnParameter>;
public readonly asgToParamMap: Map<string, CfnParameter>;
private static instance: HorizontallyScalingDeploymentPropertiesExperimental | undefined;

private constructor(scope: GuStack) {
Expand Down
16 changes: 16 additions & 0 deletions src/riff-raff-yaml-file/deployments/cloudformation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { GuAutoScalingGroup } from "../../constructs/autoscaling";
import { HorizontallyScalingDeploymentPropertiesExperimental } from "../../experimental/patterns/ec2-app";
import type { CdkStacksDifferingOnlyByStage, RiffRaffDeployment, RiffRaffDeploymentParameters } from "../types";

export function cloudFormationDeployment(
Expand Down Expand Up @@ -72,3 +73,18 @@ export function getAmiParameters(autoScalingGroups: GuAutoScalingGroup[]): RiffR
};
}, {});
}

export function getMinInstancesInServiceParameters(
autoScalingGroups: GuAutoScalingGroup[],
): RiffRaffDeploymentParameters {
return autoScalingGroups.reduce<RiffRaffDeploymentParameters>((acc, asg) => {
const { app } = asg;
const cfnParameter = HorizontallyScalingDeploymentPropertiesExperimental.getCfnParameterName(asg);
return {
...acc,
[cfnParameter]: {
App: app,
},
};
}, {});
}
111 changes: 109 additions & 2 deletions src/riff-raff-yaml-file/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { App, Duration } from "aws-cdk-lib";
import { UpdatePolicy } from "aws-cdk-lib/aws-autoscaling";
import { CfnScalingPolicy, UpdatePolicy } from "aws-cdk-lib/aws-autoscaling";
import { InstanceClass, InstanceSize, InstanceType } from "aws-cdk-lib/aws-ec2";
import { Schedule } from "aws-cdk-lib/aws-events";
import { Runtime } from "aws-cdk-lib/aws-lambda";
import { AccessScope } from "../constants";
import type { GuAutoScalingGroup } from "../constructs/autoscaling";
import type { GuStackProps } from "../constructs/core";
import { GuStack } from "../constructs/core";
import { GuLambdaFunction } from "../constructs/lambda";
import { GuEc2AppExperimental } from "../experimental/patterns/ec2-app";
import {
GuEc2AppExperimental,
HorizontallyScalingDeploymentPropertiesExperimental,
} from "../experimental/patterns/ec2-app";
import { GuEc2App, GuNodeApp, GuPlayApp, GuScheduledLambda } from "../patterns";
import { getTemplateAfterAspectInvocation } from "../utils/test";
import { RiffRaffYamlFile } from "./index";

describe("The RiffRaffYamlFile class", () => {
Expand Down Expand Up @@ -1413,4 +1418,106 @@ describe("The RiffRaffYamlFile class", () => {
"
`);
});

it("Should include minInstancesInServiceParameters when GuEc2AppExperimental has a scaling policy", () => {
const app = new App({ outdir: "/tmp/cdk.out" });

class MyApplicationStack extends GuStack {
public readonly asg: GuAutoScalingGroup;

// eslint-disable-next-line custom-rules/valid-constructors -- unit testing
constructor(app: App, id: string, props: GuStackProps) {
super(app, id, props);

const appName = "my-app";

const { autoScalingGroup } = new GuEc2AppExperimental(this, {
app: appName,
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MICRO),
access: { scope: AccessScope.PUBLIC },
userData: {
distributable: {
fileName: `${appName}.deb`,
executionStatement: `dpkg -i /${appName}/${appName}.deb`,
},
},
certificateProps: {
domainName: "rip.gu.com",
},
monitoringConfiguration: { noMonitoring: true },
scaling: {
minimumInstances: 1,
},
applicationPort: 9000,
imageRecipe: "arm64-bionic-java11-deploy-infrastructure",
buildIdentifier: "TEST",
});

new CfnScalingPolicy(autoScalingGroup, "ScaleOut", {
autoScalingGroupName: autoScalingGroup.autoScalingGroupName,
policyType: "SimpleScaling",
adjustmentType: "ChangeInCapacity",
scalingAdjustment: 1,
});

this.asg = autoScalingGroup;
}
}

const guStack = new MyApplicationStack(app, "test-stack", {
stack: "test",
stage: "TEST",
env: { region: "eu-west-1" },
});

// Ensure the Aspects are invoked...
getTemplateAfterAspectInvocation(guStack);

// ...so that the CFN Parameters are added to the template, to then be processed by the `RiffRaffYamlFile`
const actual = new RiffRaffYamlFile(app).toYAML();

const cfnParameterName = HorizontallyScalingDeploymentPropertiesExperimental.getCfnParameterName(guStack.asg);

expect(actual).toMatchInlineSnapshot(`
"allowedStages:
- TEST
deployments:
asg-upload-eu-west-1-test-my-app:
type: autoscaling
actions:
- uploadArtifacts
regions:
- eu-west-1
stacks:
- test
app: my-app
parameters:
bucketSsmLookup: true
prefixApp: true
contentDirectory: my-app
cfn-eu-west-1-test-my-application-stack:
type: cloud-formation
regions:
- eu-west-1
stacks:
- test
app: my-application-stack
contentDirectory: /tmp/cdk.out
parameters:
templateStagePaths:
TEST: test-stack.template.json
amiParametersToTags:
AMIMyapp:
BuiltBy: amigo
AmigoStage: PROD
Recipe: arm64-bionic-java11-deploy-infrastructure
Encrypted: 'true'
minInstancesInServiceParameters:
${cfnParameterName}:
App: my-app
dependencies:
- asg-upload-eu-west-1-test-my-app
"
`);
});
});
15 changes: 14 additions & 1 deletion src/riff-raff-yaml-file/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ import { dump } from "js-yaml";
import { GuAutoScalingGroup } from "../constructs/autoscaling";
import { GuStack } from "../constructs/core";
import { GuLambdaFunction } from "../constructs/lambda";
import { HorizontallyScalingDeploymentPropertiesExperimental } from "../experimental/patterns/ec2-app";
import { autoscalingDeployment, uploadAutoscalingArtifact } from "./deployments/autoscaling";
import { cloudFormationDeployment, getAmiParameters } from "./deployments/cloudformation";
import {
cloudFormationDeployment,
getAmiParameters,
getMinInstancesInServiceParameters,
} from "./deployments/cloudformation";
import { updateLambdaDeployment, uploadLambdaArtifact } from "./deployments/lambda";
import { groupByClassNameStackRegionStage } from "./group-by";
import type {
Expand Down Expand Up @@ -271,13 +276,21 @@ export class RiffRaffYamlFile {

const amiParametersToTags = getAmiParameters(autoscalingGroups);

const minInServiceParamMap =
HorizontallyScalingDeploymentPropertiesExperimental.getInstance(stack).asgToParamMap;
const minInServiceAsgs = autoscalingGroups.filter((asg) => minInServiceParamMap.has(asg.node.id));
const minInstancesInServiceParameters = getMinInstancesInServiceParameters(minInServiceAsgs);

deployments.set(cfnDeployment.name, {
...cfnDeployment.props,
parameters: {
...cfnDeployment.props.parameters,

// only add the `amiParametersToTags` property if there are some
...(autoscalingGroups.length > 0 && { amiParametersToTags }),

// only add the `minInstancesInServiceParameters` property if there are some
...(minInServiceAsgs.length > 0 && { minInstancesInServiceParameters }),
},
});
});
Expand Down

0 comments on commit c0bee66

Please sign in to comment.