Skip to content

Commit

Permalink
Merge pull request #20 from elsa-data/feature/pre-uom-demo-changes
Browse files Browse the repository at this point in the history
Lots of tidies up for uom demo
  • Loading branch information
andrewpatto authored Sep 13, 2023
2 parents f85788c + fb613de commit a7b386c
Show file tree
Hide file tree
Showing 15 changed files with 125 additions and 91 deletions.
20 changes: 12 additions & 8 deletions dev/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Application manual deploy

> :warning: \*_You must also build the workload CDK or this will not work_! See below
> :warning: \*You must also build the workload CDK or this will not work! See below
This CDK is for direct deployment to the UMCCR dev account
from a developers machine.
Expand All @@ -14,13 +14,17 @@ It is designed for rapid development so does not use CI pipelines -
it directly deploys the locally built solution - whatever is on the devs machine
gets deployed.

NOTE: THE CDK DEPLOYED IS THAT WHICH HAS BEEN BUILT IN THE WORKLOAD FOLDER
NOTE: THE CDK DEPLOYED IS THAT WHICH HAS BEEN BUILT IN
THE PACKAGES FOLDER - THAT IS THE COMPILED JAVASCRIPT
FILES AND NOT THE TYPESCRIPT

This project uses a local package reference in `package.json` - which means that
the referred package is not "built" when we do an `npm install`.
Open another window and do a `pnpm -w run watch` to make sure that
this CDK deployment is continuously being kept up to date. Then use `cdk`
directly.

That means you need to open another window and do a `npm run build` or
`npm run build:watch` (in the `workload-elsa-data-aws-application` folder)
to make sure that this CDK deployment is "up to date".
-OR-

`npm run deploy`
You can run CDK deploy/destroy steps that include a "pre-build".

`pnpm run deploy`
`pnpm run destroy`
27 changes: 9 additions & 18 deletions dev/dev-docker-image/base.json5
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,16 @@
ontoFhirUrl: "https://onto.prod.umccr.org/fhir",
releaseKeyPrefix: "R",
ipLookup: {
maxMindDbPath: "Geoacumen-Country.mmdb",
maxMindDbPath: "/dev-config/Geoacumen-Country.mmdb",
},
sharers: [
{
id: "object-signing",
type: "object-signing",
maxAgeInSeconds: 600,
},
{
id: "copy-out",
type: "copy-out",
},
{
id: "umccr-htsget",
type: "htsget",
url: "https://htsget.elsa.dev.umccr.org",
maxAgeInSeconds: 600,
},
],
feature: {
enableConsentDisplay: true,
enableCohortConstructor: true,
enableDataEgressViewer: false,
},
// datasetEgress: {
// updateInterval: "0 6 * * *", // 6am
// },
logger: {
level: "debug",
},
Expand Down
18 changes: 18 additions & 0 deletions dev/dev-docker-image/sharers.json5
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,23 @@
url: "https://htsget.elsa.dev.umccr.org",
maxAgeInSeconds: 600,
},
{
id: "parkville-ap",
type: "aws-access-point",
allowedVpcs: {
"UMCCR Nextflow Tower Research Group 1": {
accountId: "842385035780",
vpcId: "vpc-0d1e5b642f953920f",
},
"UMCCR Nextflow Tower Research Group 2": {
accountId: "842385035780",
vpcId: "vpc-0ae1fbadcf21859f3",
},
"UoM Demo": {
accountId: "534840902377",
vpcId: "vpc-031e3d24ea0e50664",
},
},
},
],
}
6 changes: 3 additions & 3 deletions dev/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ new ElsaDataStack(
},
description: descriptionWithTag(undefined),
tags: {
"umccr-org:ProductVersion": DEV_DEPLOYED_IMAGE_TAG,
"umccr-org:Stack": "ElsaDataApplication",
"umccr-org:Product": "ElsaData",
ProductVersion: DEV_DEPLOYED_IMAGE_TAG,
Stack: "ElsaDataApplication",
Product: "ElsaData",
},
},
{
Expand Down
5 changes: 4 additions & 1 deletion dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"version": "0.0.0",
"private": true,
"description": "Manual deploy of the CDK Elsa Data workload for dev purposes",
"scripts": {},
"scripts": {
"deploy": "pnpm -w run build && cdk deploy",
"destroy": "pnpm -w run build && cdk destroy"
},
"devDependencies": {
"@tsconfig/node18": "1.0.3",
"@types/node": "18.17.12",
Expand Down
1 change: 1 addition & 0 deletions packages/aws-application/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A README that should tell us about this application
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import * as apprunner from "@aws-cdk/aws-apprunner-alpha";
// WIP warning
// was used to test the concept
// waiting on a CDK construct for settings the deployed URL and then we should revisit
// THIS GETS SLOWLY OUT OF DATA WITH THE REAL APPLICATION CONSTRUCT - SO PLEASE DO A CHECK FOR CHANGES THERE
// AND IMPLEMENT HERE
//

interface Props extends StackProps {
Expand Down
23 changes: 21 additions & 2 deletions packages/aws-application/app/elsa-data-application-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Construct } from "constructs";
import { DockerServiceWithHttpsLoadBalancerConstruct } from "../construct/docker-service-with-https-load-balancer-construct";
import { Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { ISecurityGroup } from "aws-cdk-lib/aws-ec2";
import { Service } from "aws-cdk-lib/aws-servicediscovery";
import { INamespace, Service } from "aws-cdk-lib/aws-servicediscovery";
import { IHostedZone } from "aws-cdk-lib/aws-route53";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
import { ElsaDataApplicationSettings } from "../elsa-data-application-settings";
Expand All @@ -21,11 +21,13 @@ interface Props extends ElsaDataApplicationSettings {

readonly taskDefinition: TaskDefinitionConstruct;

readonly cloudMapService: Service;
readonly cloudMapNamespace: INamespace;

readonly hostedZone: IHostedZone;
readonly hostedZoneCertificate: ICertificate;

readonly deployedUrl: string;

// the security group of our edgedb - that we will put ourselves in to enable access
readonly edgeDbSecurityGroup: ISecurityGroup;

Expand Down Expand Up @@ -92,6 +94,8 @@ export class ElsaDataApplicationConstruct extends Construct {
})
);

// TODO consider moving all the "write" permissions here to be a CMD level (i.e. cluster admins only)
// and only have "read" permissions here
if (props.awsPermissions.enableAccessPoints) {
policy.addStatements(
// temporarily give all S3 accesspoint perms - can we tighten?
Expand Down Expand Up @@ -194,6 +198,21 @@ export class ElsaDataApplicationConstruct extends Construct {
props.tempBucket.grantReadWrite(
this.privateServiceWithLoadBalancer.service.taskDefinition.taskRole
);

// register a cloudMapService for the Application in our namespace
// chose a sensible default - but allow an alteration in case I guess someone might
// want to run two Elsa *in the same infrastructure*
const service = new Service(this, "CloudMapService", {
namespace: props.cloudMapNamespace,
name: "Application",
description: "Web application",
});

service.registerNonIpInstance("CloudMapCustomAttributes", {
customAttributes: {
deployedUrl: props.deployedUrl,
},
});
}

public fargateService(): FargateService {
Expand Down
11 changes: 7 additions & 4 deletions packages/aws-application/command/command-lambda/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const handler = async (event) => {
const clusterLogGroupName = process.env["CLUSTER_LOG_GROUP_NAME"];
const taskDefinitionArn = process.env["TASK_DEFINITION_ARN"];
const containerName = process.env["CONTAINER_NAME"];
const logStreamPrefix = process.env["LOG_STREAM_PREFIX"];
const subnets = process.env["SUBNETS"];
const securityGroups = process.env["SECURITY_GROUPS"];

Expand All @@ -38,17 +39,19 @@ export const handler = async (event) => {
!clusterLogGroupName ||
!taskDefinitionArn ||
!containerName ||
!logStreamPrefix ||
!subnets ||
!securityGroups
)
throw new Error(
"Cluster settings must be passed in via environment variables"
"Lambda must be invoked with cluster settings passed in via environment variables"
);

console.log(clusterArn);
console.log(clusterLogGroupName);
console.log(taskDefinitionArn);
console.log(containerName);
console.log(logStreamPrefix);
console.log(subnets);
console.log(securityGroups);

Expand Down Expand Up @@ -89,9 +92,7 @@ export const handler = async (event) => {
const taskArnSplit = taskArn.split("/");

if (taskArnSplit.length === 3) {
// TODO these come from the parent logStreamPrefix/containername
// so possibly pass these rather than fix them here
logStreamName = `elsa/ElsaData/${taskArnSplit[2]}`;
logStreamName = `${logStreamPrefix}/${containerName}/${taskArnSplit[2]}`;
}

let lastStatus = result.tasks[0].lastStatus;
Expand All @@ -111,6 +112,8 @@ export const handler = async (event) => {
await sleep(10000);
}

// we return the log group name and stream name so the bash invoker can fetch all
// the messages and display them to the user
return {
message: "Success",
logGroupName: clusterLogGroupName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ export class ElsaDataCommandConstruct extends Construct {
})
);

// the permissions of the running container (i.e all AWS functionality used by Elsa Data code)
// the permissions of the running Command container
// (i.e all AWS functionality used by Elsa Data code FOR ADMIN TASKS)
props.taskDefinition.taskDefinition.taskRole.attachInlinePolicy(policy);

// the command function is an invocable lambda that will then go and spin up an ad-hoc Task in our
Expand All @@ -86,12 +87,11 @@ export class ElsaDataCommandConstruct extends Construct {
props.appService
);

// register a cloudMapService for the Application in our namespace
// chose a sensible default - but allow an alteration in case I guess someone might
// want to run two Elsa *in the same infrastructure*
// register a cloudMapService for the Command infrastructure in our namespace
const commandService = new Service(this, "CloudMapService", {
namespace: props.cloudMapNamespace,
name: "Command",
description: "Command service for administration activity",
});

// we register it into the cloud map namespace so outside CLI tools can locate it
Expand Down Expand Up @@ -140,6 +140,7 @@ export class ElsaDataCommandConstruct extends Construct {
TASK_DEFINITION_ARN: taskDefinition.taskDefinition.taskDefinitionArn,
SERVICE_ARN: appService.serviceArn,
CONTAINER_NAME: container.containerName,
LOG_STREAM_PREFIX: taskDefinition.logStreamPrefix,
// we are passing to the lambda the subnets and security groups that need to be used
// by the Fargate task it will invoke
SUBNETS: cluster.vpc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,26 @@ type Props = {
readonly cpu: number;
readonly cpuArchitecture: CpuArchitecture;

// a string that is sent to our AWS logger to be the stream prefix
// needs to be recorded and available so that we can coordinate fetching of logs
readonly logStreamPrefix: string;
};

/**
* A construct for a TaskDefinition that can run our Elsa Data container.
* This definition gets used for both the running 24/7 website AND for
* one-off tasks that do "admin" work. They may get given different
* permissions outside of this construct.
*/
export class TaskDefinitionConstruct extends Construct {
public readonly taskDefinition: FargateTaskDefinition;
public readonly logStreamPrefix: string;

constructor(scope: Construct, id: string, props: Props) {
super(scope, id);

this.logStreamPrefix = props.logStreamPrefix;

// we do the task definition by hand as we have some specialised settings
this.taskDefinition = new FargateTaskDefinition(this, "TaskDefinition", {
runtimePlatform: {
Expand Down
5 changes: 0 additions & 5 deletions packages/aws-application/elsa-data-application-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ export interface ElsaDataApplicationSettings {
* The cpu assigned to the Elsa Data application container - defaults to something sensible
*/
readonly cpu?: number;

/**
* If present, an alternative CloudMapService name for the application - defaults to Application
*/
readonly serviceName?: string;
}

export interface ElsaDataApplicationBuildLocal {
Expand Down
Loading

0 comments on commit a7b386c

Please sign in to comment.