Skip to content

Commit

Permalink
Merge pull request #989 from guardian/mob/obligatron
Browse files Browse the repository at this point in the history
Create "obligatron" lambda
  • Loading branch information
AshCorr authored May 21, 2024
2 parents 3b3950e + 5de0c93 commit 2fbab24
Show file tree
Hide file tree
Showing 17 changed files with 710 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ jobs:
- packages/dependency-graph-integrator/dist/dependency-graph-integrator.zip
github-actions-usage:
- packages/github-actions-usage/dist/github-actions-usage.zip
obligatron:
- packages/obligatron/dist/obligatron.zip
prisma:
- packages/common/prisma.zip
theguardian-servicecatalogue-app:
Expand Down
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,10 @@ module.exports = {
transform,
testMatch: ['<rootDir>/packages/snyk-integrator/**/*.test.ts'],
},
{
displayName: 'obligatron',
transform,
testMatch: ['<rootDir>/packages/obligatron/**/*.test.ts'],
},
],
};
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

277 changes: 277 additions & 0 deletions packages/cdk/lib/__snapshots__/service-catalogue.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exports[`The ServiceCatalogue stack matches the snapshot 1`] = `
"GuLambdaFunction",
"GuScheduledLambda",
"GuLambdaFunction",
"GuLambdaFunction",
],
"gu:cdk:version": "TEST",
},
Expand Down Expand Up @@ -18348,6 +18349,282 @@ spec:
"Type": "AWS::SecretsManager::Secret",
"UpdateReplacePolicy": "Delete",
},
"obligatronA58CFCF1": {
"DependsOn": [
"obligatronServiceRoleDefaultPolicyC8AE10A2",
"obligatronServiceRole1E85277A",
],
"Properties": {
"Architectures": [
"arm64",
],
"Code": {
"S3Bucket": {
"Ref": "DistributionBucketName",
},
"S3Key": "deploy/TEST/obligatron/obligatron.zip",
},
"Environment": {
"Variables": {
"APP": "obligatron",
"DATABASE_HOSTNAME": {
"Fn::GetAtt": [
"PostgresInstance16DE4286E",
"Endpoint.Address",
],
},
"QUERY_LOGGING": "false",
"STACK": "deploy",
"STAGE": "TEST",
},
},
"Handler": "index.main",
"LoggingConfig": {
"LogFormat": "JSON",
},
"MemorySize": 4096,
"Role": {
"Fn::GetAtt": [
"obligatronServiceRole1E85277A",
"Arn",
],
},
"Runtime": "nodejs20.x",
"Tags": [
{
"Key": "App",
"Value": "obligatron",
},
{
"Key": "gu:cdk:version",
"Value": "TEST",
},
{
"Key": "gu:repo",
"Value": "guardian/service-catalogue",
},
{
"Key": "Stack",
"Value": "deploy",
},
{
"Key": "Stage",
"Value": "TEST",
},
],
"Timeout": 300,
"VpcConfig": {
"SecurityGroupIds": [
{
"Fn::GetAtt": [
"PostgresAccessSecurityGroupServicecatalogue03C78F14",
"GroupId",
],
},
],
"SubnetIds": {
"Ref": "PrivateSubnets",
},
},
},
"Type": "AWS::Lambda::Function",
},
"obligatronServiceRole1E85277A": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com",
},
},
],
"Version": "2012-10-17",
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
],
],
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",
],
],
},
],
"Tags": [
{
"Key": "App",
"Value": "obligatron",
},
{
"Key": "gu:cdk:version",
"Value": "TEST",
},
{
"Key": "gu:repo",
"Value": "guardian/service-catalogue",
},
{
"Key": "Stack",
"Value": "deploy",
},
{
"Key": "Stage",
"Value": "TEST",
},
],
},
"Type": "AWS::IAM::Role",
},
"obligatronServiceRoleDefaultPolicyC8AE10A2": {
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":s3:::",
{
"Ref": "DistributionBucketName",
},
],
],
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":s3:::",
{
"Ref": "DistributionBucketName",
},
"/deploy/TEST/obligatron/obligatron.zip",
],
],
},
],
},
{
"Action": "ssm:GetParametersByPath",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:ssm:",
{
"Ref": "AWS::Region",
},
":",
{
"Ref": "AWS::AccountId",
},
":parameter/TEST/deploy/obligatron",
],
],
},
},
{
"Action": [
"ssm:GetParameters",
"ssm:GetParameter",
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:ssm:",
{
"Ref": "AWS::Region",
},
":",
{
"Ref": "AWS::AccountId",
},
":parameter/TEST/deploy/obligatron/*",
],
],
},
},
{
"Action": "rds-db:connect",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":rds-db:",
{
"Ref": "AWS::Region",
},
":",
{
"Ref": "AWS::AccountId",
},
":dbuser:",
{
"Fn::GetAtt": [
"PostgresInstance16DE4286E",
"DbiResourceId",
],
},
"/obligatron",
],
],
},
},
],
"Version": "2012-10-17",
},
"PolicyName": "obligatronServiceRoleDefaultPolicyC8AE10A2",
"Roles": [
{
"Ref": "obligatronServiceRole1E85277A",
},
],
},
"Type": "AWS::IAM::Policy",
},
"prismamigratetaskTEST59D4C0E8": {
"Properties": {
"AssumeRolePolicyDocument": {
Expand Down
40 changes: 40 additions & 0 deletions packages/cdk/lib/obligatron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { GuStack } from '@guardian/cdk/lib/constructs/core';
import type { GuSecurityGroup } from '@guardian/cdk/lib/constructs/ec2';
import { GuLambdaFunction } from '@guardian/cdk/lib/constructs/lambda';
import { Duration } from 'aws-cdk-lib';
import type { IVpc } from 'aws-cdk-lib/aws-ec2';
import { Architecture, Runtime } from 'aws-cdk-lib/aws-lambda';
import type { DatabaseInstance } from 'aws-cdk-lib/aws-rds';

type ObligatronProps = {
vpc: IVpc;
dbAccess: GuSecurityGroup;
db: DatabaseInstance;
};

export class Obligatron {
constructor(stack: GuStack, props: ObligatronProps) {
const { vpc, dbAccess, db } = props;
const app = 'obligatron';

const lambda = new GuLambdaFunction(stack, 'obligatron', {
app,
vpc,
architecture: Architecture.ARM_64,
runtime: Runtime.NODEJS_20_X,
securityGroups: [dbAccess],
fileName: `${app}.zip`,
handler: 'index.main',
environment: {
DATABASE_HOSTNAME: db.dbInstanceEndpointAddress,
QUERY_LOGGING: 'false', // Set this to 'true' to enable SQL query logging
},
timeout: Duration.minutes(5),
// Unfortunately Prisma doesn't support streaming data from Postgres at the moment https://github.com/prisma/prisma/issues/5055
// This means that all rows need to be loaded into memory at the same time whenever a query is ran hence the high memory requirement.
memorySize: 4096,
});

db.grantConnect(lambda, 'obligatron');
}
}
7 changes: 7 additions & 0 deletions packages/cdk/lib/service-catalogue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { addCloudqueryEcsCluster } from './cloudquery';
import { addDataAuditLambda } from './data-audit';
import { addGithubActionsUsageLambda } from './github-actions-usage';
import { InteractiveMonitor } from './interactive-monitor';
import { Obligatron } from './obligatron';
import { addPrismaMigrateTask } from './prisma-migrate-task';
import { Repocop } from './repocop';

Expand Down Expand Up @@ -256,5 +257,11 @@ export class ServiceCatalogue extends GuStack {
dbAccess: applicationToPostgresSecurityGroup,
cluster: cloudqueryCluster,
});

new Obligatron(this, {
vpc,
db,
dbAccess: applicationToPostgresSecurityGroup,
});
}
}
4 changes: 4 additions & 0 deletions packages/obligatron/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
index.js

# Generated files
dist
Loading

0 comments on commit 2fbab24

Please sign in to comment.