Skip to content

Commit

Permalink
cdk deploy works but sfr is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
ryyakobe committed Jan 19, 2021
1 parent 6096f2b commit b6965e9
Show file tree
Hide file tree
Showing 12 changed files with 478 additions and 371 deletions.
131 changes: 110 additions & 21 deletions examples/deadline/All-In-AWS-Infrastructure-SEP/ts/lib/sep-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
*/

import {
CfnClientVpnAuthorizationRule,
CfnClientVpnEndpoint,
CfnClientVpnTargetNetworkAssociation,
InstanceClass,
InstanceSize,
InstanceType,
GenericLinuxImage,
SecurityGroup,
Vpc,
} from '@aws-cdk/aws-ec2';
Expand All @@ -13,16 +20,18 @@ import {
Stack,
StackProps
} from '@aws-cdk/core';
import {
ManagedPolicy,
Role,
ServicePrincipal
} from '@aws-cdk/aws-iam';
// import {
// ManagedPolicy,
// Role,
// ServicePrincipal
// } from '@aws-cdk/aws-iam';
import {
RenderQueue,
Repository,
Stage,
ThinkboxDockerRecipes,
SEPConfigurationSetup,
SEPSpotFleet,
} from 'aws-rfdk/deadline';

/**
Expand All @@ -47,7 +56,10 @@ export class SEPStack extends Stack {
constructor(scope: Construct, id: string, props: SEPStackProps) {
super(scope, id, props);

const vpc = new Vpc(this, 'Vpc', { maxAzs: 2 });
const vpc = new Vpc(this, 'Vpc', {
maxAzs: 2,
cidr: '10.100.0.0/16',
});

const recipes = new ThinkboxDockerRecipes(this, 'Image', {
stage: Stage.fromDirectory(props.dockerRecipesStagePath),
Expand Down Expand Up @@ -84,25 +96,102 @@ export class SEPStack extends Stack {
});
workerSecurityGroup.connections.allowToDefaultPort(renderQueue.endpoint);

// Create the IAM Role for the Spot Event Plugins workers.
// Note: This Role MUST have a roleName that begins with "DeadlineSpot"
// Note if you already have a worker IAM role in your account you can remove this code.
new Role( this, 'SpotWorkerRole', {
assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName('AWSThinkboxDeadlineSpotEventPluginWorkerPolicy'),
// // Create the IAM Role for the Spot Event Plugins workers.
// // Note: This Role MUST have a roleName that begins with "DeadlineSpot"
// // Note if you already have a worker IAM role in your account you can remove this code.
// const role = new Role( this, 'SpotWorkerRole', {
// assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
// managedPolicies: [
// ManagedPolicy.fromAwsManagedPolicyName('AWSThinkboxDeadlineSpotEventPluginWorkerPolicy'),
// ],
// roleName: 'DeadlineSpotWorkerRole55667',
// });

// // Creates the Resource Tracker Access role. This role is required to exist in your account so the resource tracker will work properly
// // Note: If you already have a Resource Tracker IAM role in your account you can remove this code.
// new Role( this, 'ResourceTrackerRole', {
// assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
// managedPolicies: [
// ManagedPolicy.fromAwsManagedPolicyName('AWSThinkboxDeadlineResourceTrackerAccessPolicy'),
// ],
// roleName: 'DeadlineResourceTrackerAccessRole',
// });

const fleet = new SEPSpotFleet(this, 'TestpotFleet1', {
vpc,
renderQueue: renderQueue,
// role: role,
securityGroups: [
workerSecurityGroup,
],
roleName: 'DeadlineSpotWorkerRole',
deadlineGroups: [
'group_name1',
],
instanceTypes: [
InstanceType.of(InstanceClass.T3, InstanceSize.LARGE),
],
workerMachineImage: new GenericLinuxImage({
[this.region]: 'ami-0f5650d87270255ae',
}),
targetCapacity: 1,
});

// WHEN
new SEPConfigurationSetup(this, 'SEPConfigurationSetup', {
vpc,
renderQueue: renderQueue,
spotFleetOptions: {
spotFleets: [
fleet,
],
groupPools: {
group_name1: ['pool1', 'pool2'],
},
enableResourceTracker: false,
},
});

// Creates the Resource Tracker Access role. This role is required to exist in your account so the resource tracker will work properly
// Note: If you already have a Resource Tracker IAM role in your account you can remove this code.
new Role( this, 'ResourceTrackerRole', {
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName('AWSThinkboxDeadlineResourceTrackerAccessPolicy'),
// TODO: remove this. Only for testing

const securityGroup = new SecurityGroup(this, 'SG-VPN-RFDK', {
vpc,
});

const endpoint = new CfnClientVpnEndpoint(this, 'ClientVpnEndpointRFDK', {
description: "VPN",
vpcId: vpc.vpcId,
securityGroupIds: [
securityGroup.securityGroupId,
],
roleName: 'DeadlineResourceTrackerAccessRole',
authenticationOptions: [{
type: "certificate-authentication",
mutualAuthentication: {
clientRootCertificateChainArn: "arn:aws:acm:us-east-1:693238537026:certificate/5ce1c76e-c2e1-4da1-b47a-8273af60a766",
},
}],
clientCidrBlock: '10.200.0.0/16',
connectionLogOptions: {
enabled: false,
},
serverCertificateArn: "arn:aws:acm:us-east-1:693238537026:certificate/acc475c0-eaf1-4d6a-9367-d294927565d6",
});

let i = 0;
vpc.privateSubnets.map(subnet => {
new CfnClientVpnTargetNetworkAssociation(this, `ClientVpnNetworkAssociation${i}`, {
clientVpnEndpointId: endpoint.ref,
subnetId: subnet.subnetId,
});
i++;
});

new CfnClientVpnAuthorizationRule(this, 'ClientVpnAuthRule', {
clientVpnEndpointId: endpoint.ref,
targetNetworkCidr: '10.100.0.0/16',
authorizeAllGroups: true,
description: "Allow access to whole VPC CIDR range"
});

renderQueue.connections.allowDefaultPortFrom(securityGroup);
}
}
133 changes: 57 additions & 76 deletions packages/aws-rfdk/lib/deadline/lib/sep-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

/* eslint-disable no-console */

import * as path from 'path';

import {
Expand Down Expand Up @@ -42,83 +44,10 @@ import {
SEPSpotFleet,
} from './sep-spotfleet';

// TODO: remove this, we will import it properly
export class EventPluginRequests {
constructor() {}

public async saveServerData(): Promise<boolean> {
return true;
}

public async saveSpotFleetRequestData(): Promise<boolean> {
return true;
}
}

// TODO: Probably we can get all this info from the renderqueue instead of
// readonly deadlineClient: DeadlineClientProperties;
// /**
// * User added to the $external admin database.
// * Referencing: https://docs.mongodb.com/v3.6/core/security-x.509/#member-certificate-requirements
// */
// export interface DeadlineClientProperties {
// /**
// * The IP address or DNS name of the Remote Connection Server
// */
// readonly host: string;

// /**
// * The port number address of the Remote Connection Server
// */
// readonly port: number;

// /**
// * CA certificate
// */
// readonly certificate?: ISecret;

// /**
// * The PFX certificate
// */
// readonly pfx?: ISecret;

// /**
// * Shared passphrase used for a single private key and/or a PFX.
// */
// readonly passphrase?: ISecret;
// }

// export interface IConnectionOptions {
// /**
// * FQDN of the host to connect to.
// */
// readonly hostname: string;

// /**
// * Port on the host that is serving MongoDB.
// */
// readonly port: string;

// /**
// * ARN of a Secret containing the CA. The contents must be a PEM-encoded certificate in the SecretString of the secret.
// */
// readonly caCertificate?: string;

// /**
// * ARN of a Secret containing the PFX. The contents must be a PEM-encoded certificate in the SecretString of the secret.
// */
// readonly pfxCertificate?: string;
// }

/**
* The input to this Custom Resource
*/
export interface ISEPConfigurationProperties {
// /**
// * Connection info for logging into the server.
// */
// readonly connection: IConnectionOptions;

/**
* TODO: add description
*/
Expand Down Expand Up @@ -248,15 +177,39 @@ export class SEPConfigurationSetup extends Construct {
logRetention: RetentionDays.ONE_WEEK,
});

// lamdbaFunc.connections.allowTo(props.mongoDb, Port.tcp(props.mongoDb.port));
lamdbaFunc.connections.allowToDefaultPort(props.renderQueue); // TODO: or maybe Port.tcp(props.renderQueue.endpoint.port)
// props.renderQueue.certificateChain.grantRead(lamdbaFunc.grantPrincipal);
// props.mongoDb.adminUser.grantRead(lamdbaFunc.grantPrincipal);
// props.users.passwordAuthUsers?.forEach( secret => secret.grantRead(lamdbaFunc) );
// props.users.x509AuthUsers?.forEach( user => user.certificate.grantRead(lamdbaFunc) );

const combinedSpotFleetConfigs = this.combinedSpotFleetConfigs(props.spotFleetOptions?.spotFleets);

const properties: ISEPConfiguratorResourceProperties = {
spotFleetRequestConfiguration: 'TODO:createCOnfigFromThis',
spotPluginConfigurations: 'TODO:createConfigFromThis',
connection: {
hostname: props.renderQueue.endpoint.hostname,
port: props.renderQueue.endpoint.portNumber,
// caCertificate: props.renderQueue.configureClientECS,
// pfxCertificate: props.renderQueue.pfxCertificate,
// passphrase: props.renderQueue.passphrase,
},
spotFleetRequestConfigurations: combinedSpotFleetConfigs,
spotPluginConfigurations: {
AWSInstanceStatus: props.spotFleetOptions?.awsInstanceStatus,
DeleteInterruptedSlaves: props.spotFleetOptions?.deleteEC2SpotInterruptedWorkers,
DeleteTerminatedSlaves: props.spotFleetOptions?.deleteSEPTerminatedWorkers,
GroupPools: props.spotFleetOptions?.groupPools ? JSON.stringify(props.spotFleetOptions?.groupPools) : undefined, // TODO:
IdleShutdown: props.spotFleetOptions?.idleShutdown,
Logging: props.spotFleetOptions?.loggingLevel,
NamedProfile: '',
PreJobTaskMode: props.spotFleetOptions?.preJobTaskMode,
Region: props.spotFleetOptions?.region,
ResourceTracker: props.spotFleetOptions?.enableResourceTracker,
StaggerInstances: props.spotFleetOptions?.maximumInstancesStartedPerCycle,
State: props.spotFleetOptions?.state,
StrictHardCap: props.spotFleetOptions?.strictHardCap,
UseLocalCredentials: true,
},
};

const resource = new CustomResource(this, 'Default', {
Expand All @@ -276,4 +229,32 @@ export class SEPConfigurationSetup extends Construct {

this.node.defaultChild = resource;
}

private combinedSpotFleetConfigs(spotFleets?: SEPSpotFleet[]): string | undefined {
// TODO: maybe also check if it's empty?
if (!spotFleets) {
return undefined;
}

let allGroupConfigMappings: any[] = [];

spotFleets.map(fleet => {
allGroupConfigMappings = allGroupConfigMappings.concat(fleet.sepSpotFleetRequestConfigurations);
});

let fullSpotFleetRequestConfiguration: any = {};
allGroupConfigMappings.map(mapping => {
for (const [key, value] of Object.entries(mapping)) {
fullSpotFleetRequestConfiguration[key] = value;
}
});

// console.log('As string CDK:');
// console.log(Stack.of(this).toJsonString(fullSpotFleetRequestConfiguration));

// console.log('As string JSON:');
// console.log(JSON.stringify(fullSpotFleetRequestConfiguration));

return Stack.of(this).toJsonString(fullSpotFleetRequestConfiguration); // TODO: should we just use JSON.Stringify here?
}
}
Loading

0 comments on commit b6965e9

Please sign in to comment.