Skip to content

Commit

Permalink
feat: add ssm patching stack (#723)
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Alvarez <alvajus@amazon.com>
  • Loading branch information
pendo324 authored Sep 26, 2024
1 parent 5e6feb5 commit 5e39bd7
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 6 deletions.
2 changes: 1 addition & 1 deletion config/runner-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface RunnerType {
availabilityZones: Array<string>;
}

export enum PlatformType {
export const enum PlatformType {
WINDOWS = 'windows',
MAC = 'mac',
AMAZONLINUX = 'amazonlinux',
Expand Down
3 changes: 3 additions & 0 deletions lib/finch-pipeline-app-stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ContinuousIntegrationStack } from './continuous-integration-stack';
import { ECRRepositoryStack } from './ecr-repo-stack';
import { EventBridgeScanNotifsStack } from './event-bridge-scan-notifs-stack';
import { PVREReportingStack } from './pvre-reporting-stack';
import { SSMPatchingStack } from './ssm-patching-stack';

export enum ENVIRONMENT_STAGE {
Beta,
Expand Down Expand Up @@ -76,5 +77,7 @@ export class FinchPipelineAppStage extends cdk.Stage {
}

new PVREReportingStack(this, 'PVREReportingStack', { terminationProtection: true });

new SSMPatchingStack(this, 'SSMPatchingStack', { terminationProtection: true });
}
}
56 changes: 56 additions & 0 deletions lib/ssm-patching-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as cdk from 'aws-cdk-lib';
import { CfnMaintenanceWindow, CfnMaintenanceWindowTarget, CfnMaintenanceWindowTask } from 'aws-cdk-lib/aws-ssm';
import { Construct } from 'constructs';
import { applyTerminationProtectionOnStacks } from './aspects/stack-termination-protection';

export class SSMPatchingStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
applyTerminationProtectionOnStacks([this]);

const maintenanceWindow = new CfnMaintenanceWindow(this, 'MaintenanceWindow', {
name: `Patching-Window`,
allowUnassociatedTargets: false,
cutoff: 0,
duration: 2,
// Every Sunday at 3 AM
schedule: 'cron(0 3 ? * SUN *)'
});

const maintenanceTarget = new CfnMaintenanceWindowTarget(this, 'MaintenanceWindowTarget', {
name: 'All-Instances-Patch-Target',
windowId: maintenanceWindow.ref,
resourceType: 'INSTANCE',
targets: [
{
key: 'tag:PVRE-Reporting',
values: ['SSM']
}
]
});

new CfnMaintenanceWindowTask(this, 'MaintenanceWindowTask', {
taskArn: 'AWS-RunPatchBaseline',
priority: 1,
taskType: 'RUN_COMMAND',
windowId: maintenanceWindow.ref,
name: 'Patch-Task',
targets: [
{
key: 'WindowTargetIds',
values: [maintenanceTarget.ref]
}
],
taskInvocationParameters: {
maintenanceWindowRunCommandParameters: {
parameters: {
Operation: ['Install']
},
documentVersion: '$LATEST'
}
},
maxErrors: '0',
maxConcurrency: '1'
});
}
}
2 changes: 1 addition & 1 deletion test/artifact-bucket-cloudfront.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cdk from 'aws-cdk-lib';
import { Template, Match } from 'aws-cdk-lib/assertions';
import { Match, Template } from 'aws-cdk-lib/assertions';
import { ArtifactBucketCloudfrontStack } from '../lib/artifact-bucket-cloudfront';

describe('ArtifactBucketCloudfrontStack', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/cloudfront_cdn.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cdk from 'aws-cdk-lib';
import { Template, Match } from 'aws-cdk-lib/assertions';
import { Match, Template } from 'aws-cdk-lib/assertions';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { CfnBucket } from 'aws-cdk-lib/aws-s3';
import { CloudfrontCdn } from '../lib/cloudfront_cdn';
Expand Down
2 changes: 1 addition & 1 deletion test/ecr-repo-stack.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cdk from 'aws-cdk-lib';
import { Template, Match } from 'aws-cdk-lib/assertions';
import { Match, Template } from 'aws-cdk-lib/assertions';
import { ECRRepositoryStack } from '../lib/ecr-repo-stack';

describe('ECRRepositoryStack', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/event-bridge-scan-notifs-stack.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as cdk from 'aws-cdk-lib';
import { Template, Match } from 'aws-cdk-lib/assertions';
import { Match, Template } from 'aws-cdk-lib/assertions';
import { EventBridgeScanNotifsStack } from '../lib/event-bridge-scan-notifs-stack';

describe('EventBridgeScanNotifsStack', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/finch-pipeline-stack.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as cdk from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { FinchPipelineStack } from '../lib/finch-pipeline-stack';
import { EnvConfig } from '../config/env-config';
import { FinchPipelineStack } from '../lib/finch-pipeline-stack';

describe('FinchPipelineStack', () => {
test('synthesizes the way we expect', () => {
Expand Down
72 changes: 72 additions & 0 deletions test/ssm-patching-stack.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import * as cdk from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { SSMPatchingStack } from '../lib/ssm-patching-stack';

describe('SSMPatchingStack', () => {
test('synthesizes the way we expect', () => {
const app = new cdk.App();
const ssmPatchingStack = new SSMPatchingStack(app, 'SSMPatchingStack');

const template = Template.fromStack(ssmPatchingStack);

template.hasResource('AWS::SSM::MaintenanceWindow', {
Properties: {
AllowUnassociatedTargets: false,
Cutoff: 0,
Duration: 2,
Name: 'Patching-Window',
Schedule: 'cron(0 3 ? * SUN *)'
}
});

template.hasResource('AWS::SSM::MaintenanceWindowTarget', {
Properties: {
Name: 'All-Instances-Patch-Target',
ResourceType: 'INSTANCE',
Targets: [
{
Key: 'tag:PVRE-Reporting',
Values: ['SSM']
}
],
WindowId: {
Ref: 'MaintenanceWindow'
}
}
});

template.hasResource('AWS::SSM::MaintenanceWindowTask', {
Properties: {
MaxConcurrency: '1',
MaxErrors: '0',
Name: 'Patch-Task',
Priority: 1,
Targets: [
{
Key: 'WindowTargetIds',
Values: [
{
Ref: 'MaintenanceWindowTarget'
}
]
}
],
TaskArn: 'AWS-RunPatchBaseline',
TaskInvocationParameters: {
MaintenanceWindowRunCommandParameters: {
Parameters: {
Operation: ['Install']
},
DocumentVersion: '$LATEST'
}
},
TaskType: 'RUN_COMMAND',
WindowId: {
Ref: 'MaintenanceWindow'
}
}
});

expect(ssmPatchingStack.terminationProtection).toBeTruthy();
});
});

0 comments on commit 5e39bd7

Please sign in to comment.